0027961: Visualization - remove unused and no more working OpenGl_AVIWriter
[occt.git] / src / BRepMesh / BRepMesh_FastDiscret.cxx
CommitLineData
b311480e 1// Created on: 1996-02-27
2// Created by: Ekaterina SMIRNOVA
3// Copyright (c) 1996-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 8// This library is free software; you can redistribute it and/or modify it under
9// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 10// by the Free Software Foundation, with special exception defined in the file
11// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12// distribution for complete text of the license and disclaimer of any warranty.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
fc9b36d6 17#include <BRepMesh_FastDiscret.hxx>
7fd59977 18
fc9b36d6 19#include <BRepMesh_WireChecker.hxx>
7fd59977 20#include <BRepMesh_FastDiscretFace.hxx>
21#include <BRepMesh_FaceAttribute.hxx>
22#include <BRepMesh_DataStructureOfDelaun.hxx>
7fd59977 23#include <BRepMesh_GeomTool.hxx>
24#include <BRepMesh_PairOfPolygon.hxx>
fc9b36d6 25#include <BRepMesh_Classifier.hxx>
ceb418e1 26#include <BRepMesh_EdgeParameterProvider.hxx>
27#include <BRepMesh_IEdgeTool.hxx>
28#include <BRepMesh_EdgeTessellator.hxx>
29#include <BRepMesh_EdgeTessellationExtractor.hxx>
7fd59977 30
31#include <BRepAdaptor_Curve.hxx>
32#include <BRepAdaptor_Surface.hxx>
33#include <BRepAdaptor_HSurface.hxx>
fc9b36d6 34
35#include <Bnd_Box.hxx>
7fd59977 36#include <BRepTools.hxx>
7fd59977 37#include <BRepBndLib.hxx>
fc9b36d6 38#include <BndLib_Add3dCurve.hxx>
fc9b36d6 39#include <Poly_Triangulation.hxx>
40#include <Poly_PolygonOnTriangulation.hxx>
7fd59977 41
fc9b36d6 42#include <Precision.hxx>
7fd59977 43#include <Geom2d_Curve.hxx>
81093856 44#include <Geom2dAdaptor_HCurve.hxx>
7fd59977 45#include <Geom_Surface.hxx>
fc9b36d6 46#include <Geom_Plane.hxx>
47#include <GeomAbs_SurfaceType.hxx>
7fd59977 48#include <Extrema_LocateExtPC.hxx>
49
7fd59977 50#include <TColStd_Array1OfInteger.hxx>
e1c1b6b9 51#include <TColStd_Array1OfCharacter.hxx>
fc9b36d6 52#include <TColStd_HArray1OfReal.hxx>
fc9b36d6 53#include <TColgp_Array1OfPnt2d.hxx>
7fd59977 54#include <TColGeom2d_SequenceOfCurve.hxx>
fc9b36d6 55
7fd59977 56#include <TopTools_SequenceOfShape.hxx>
fc9b36d6 57#include <TopTools_ListIteratorOfListOfShape.hxx>
fc9b36d6 58
59#include <TopAbs.hxx>
60#include <TopoDS.hxx>
61#include <TopoDS_Vertex.hxx>
62#include <TopExp.hxx>
63#include <TopExp_Explorer.hxx>
64
c7b59798 65#include <OSD_Parallel.hxx>
66
fc9b36d6 67#include <Standard_ErrorHandler.hxx>
68#include <Standard_Failure.hxx>
7fd59977 69#include <NCollection_IncAllocator.hxx>
70
71#include <BRep_ListIteratorOfListOfPointRepresentation.hxx>
72#include <BRep_PointRepresentation.hxx>
7fd59977 73
74#include <vector>
75
92efcf78 76IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_FastDiscret,Standard_Transient)
77
51c3cc5f
O
78#define UVDEFLECTION 1.e-05
79
7fd59977 80//=======================================================================
81//function : BRepMesh_FastDiscret
82//purpose :
83//=======================================================================
e71669c6 84BRepMesh_FastDiscret::BRepMesh_FastDiscret( const Bnd_Box& theBox,
85 const BRepMesh_FastDiscret::Parameters& theParams)
86 :
e1c1b6b9 87 myMapdefle(1000, new NCollection_IncAllocator()),
848fa7e3 88 myBoundaryVertices(new BRepMesh::DMapOfVertexInteger),
a319f03f 89 myBoundaryPoints(new BRepMesh::DMapOfIntegerPnt),
e71669c6 90 myParameters(theParams),
91 myDtotale(0.)
92{
93 if ( myParameters.Relative )
fc9b36d6 94 BRepMesh_ShapeTool::BoxMaxDimension(theBox, myDtotale);
7fd59977 95}
96
0981302b 97//=======================================================================
ceb418e1 98//function : InitSharedFaces
99//purpose :
0981302b 100//=======================================================================
ceb418e1 101void BRepMesh_FastDiscret::InitSharedFaces(const TopoDS_Shape& theShape)
0981302b 102{
ceb418e1 103 TopExp::MapShapesAndAncestors(theShape, TopAbs_EDGE, TopAbs_FACE, mySharedFaces);
0981302b
K
104}
105
0981302b 106//=======================================================================
7fd59977 107//function : Perform(shape)
108//purpose :
109//=======================================================================
703a6abd 110void BRepMesh_FastDiscret::Perform(const TopoDS_Shape& theShape)
7fd59977 111{
ceb418e1 112 InitSharedFaces(theShape);
113
7fd59977 114 std::vector<TopoDS_Face> aFaces;
ceb418e1 115 TopExp_Explorer anExplorer(theShape, TopAbs_FACE);
116 for (; anExplorer.More(); anExplorer.Next())
117 {
118 const TopoDS_Face& aFace = TopoDS::Face(anExplorer.Current());
119 Add(aFace);
120 aFaces.push_back(aFace);
7fd59977 121 }
0b97567d 122
e71669c6 123 OSD_Parallel::ForEach(aFaces.begin(), aFaces.end(), *this, !myParameters.InParallel);
7fd59977 124}
125
126
127//=======================================================================
128//function : Process
129//purpose :
130//=======================================================================
7fd59977 131void BRepMesh_FastDiscret::Process(const TopoDS_Face& theFace) const
132{
ceb418e1 133 Handle(BRepMesh_FaceAttribute) anAttribute;
134 if (GetFaceAttribute(theFace, anAttribute))
7fd59977 135 {
ceb418e1 136 try
137 {
138 OCC_CATCH_SIGNALS
139
e71669c6 140 BRepMesh_FastDiscretFace aTool(myParameters.Angle, myParameters.MinSize,
141 myParameters.InternalVerticesMode, myParameters.ControlSurfaceDeflection);
fcf15f5c 142 aTool.Perform(anAttribute);
ceb418e1 143 }
144 catch (Standard_Failure)
145 {
146 anAttribute->SetStatus(BRepMesh_Failure);
147 }
7fd59977 148 }
7fd59977 149}
150
2caff0b3 151//=======================================================================
152//function : resetDataStructure
153//purpose :
154//=======================================================================
155void BRepMesh_FastDiscret::resetDataStructure()
156{
157 Handle(NCollection_IncAllocator) aAllocator;
158 if (myAttribute->ChangeStructure().IsNull())
159 aAllocator = new NCollection_IncAllocator(BRepMesh::MEMORY_BLOCK_SIZE_HUGE);
160 else
161 aAllocator = myAttribute->ChangeStructure()->Allocator();
162
163 myAttribute->Clear();
164 aAllocator->Reset(Standard_False);
165 Handle(BRepMesh_DataStructureOfDelaun) aStructure =
166 new BRepMesh_DataStructureOfDelaun(aAllocator);
167
168 const Standard_Real aTolU = myAttribute->ToleranceU();
169 const Standard_Real aTolV = myAttribute->ToleranceV();
170 const Standard_Real uCellSize = 14.0 * aTolU;
171 const Standard_Real vCellSize = 14.0 * aTolV;
172
173 aStructure->Data()->SetCellSize ( uCellSize, vCellSize);
174 aStructure->Data()->SetTolerance( aTolU , aTolV );
175
176 myAttribute->ChangeStructure() = aStructure;
177}
178
7fd59977 179//=======================================================================
180//function : Add(face)
181//purpose :
182//=======================================================================
ceb418e1 183Standard_Integer BRepMesh_FastDiscret::Add(const TopoDS_Face& theFace)
7fd59977 184{
0a2a7b46 185 myAttribute.Nullify();
186 GetFaceAttribute(theFace, myAttribute, Standard_True);
187
7fd59977 188 try
189 {
190 OCC_CATCH_SIGNALS
7fd59977 191
ceb418e1 192 // Initialize face attributes
0a2a7b46 193 if (!myAttribute->IsInitialized ())
194 myAttribute->SetFace (theFace, myParameters.AdaptiveMin);
e71669c6 195
2caff0b3 196 BRepMesh::HIMapOfInteger& aVertexEdgeMap = myAttribute->ChangeVertexEdgeMap();
197 BRepMesh::HDMapOfShapePairOfPolygon& aInternalEdges = myAttribute->ChangeInternalEdges();
198
199 resetDataStructure();
7fd59977 200
e1c1b6b9 201 Standard_Real defedge = myParameters.Deflection;
ceb418e1 202 Standard_Integer nbEdge = 0;
e71669c6 203 Standard_Real savangle = myParameters.Angle;
ceb418e1 204 Standard_Real cdef;
205 Standard_Real maxdef = 2.* BRepMesh_ShapeTool::MaxFaceTolerance(theFace);
7fd59977 206
ceb418e1 207 Standard_Real defface = 0.;
e71669c6 208 if (!myParameters.Relative)
81093856 209 {
210 defedge = Max(UVDEFLECTION, defedge);
e71669c6 211 defface = Max(myParameters.Deflection, maxdef);
81093856 212 }
7fd59977 213
ceb418e1 214 const TopoDS_Face& aFace = myAttribute->Face();
e1c1b6b9 215 for (TopoDS_Iterator aWireIt(aFace); aWireIt.More(); aWireIt.Next())
ceb418e1 216 {
e1c1b6b9 217 for (TopoDS_Iterator aEdgeIt(aWireIt.Value()); aEdgeIt.More(); aEdgeIt.Next(), ++nbEdge)
ceb418e1 218 {
e1c1b6b9 219 const TopoDS_Edge& aEdge = TopoDS::Edge(aEdgeIt.Value());
220 if (aEdge.IsNull())
221 continue;
81093856 222 if (myParameters.Relative)
ceb418e1 223 {
81093856 224 if (!myMapdefle.IsBound(aEdge))
ceb418e1 225 {
226 if (myEdges.IsBound(aEdge))
227 {
228 const BRepMesh_PairOfPolygon& aPair = myEdges.Find(aEdge);
229 const Handle(Poly_PolygonOnTriangulation)& aPolygon = aPair.First();
230 defedge = aPolygon->Deflection();
231 }
232 else
233 {
234 defedge = BRepMesh_ShapeTool::RelativeEdgeDeflection(
e71669c6 235 aEdge, myParameters.Deflection, myDtotale, cdef);
ceb418e1 236
e71669c6 237 myParameters.Angle = savangle * cdef;
ceb418e1 238 }
ceb418e1 239 }
240 else
241 {
81093856 242 defedge = myMapdefle(aEdge);
703a6abd 243 }
fc9b36d6 244
81093856 245 defface += defedge;
246 defface = Max(maxdef, defface);
247
248 if (!myMapdefle.IsBound(aEdge))
249 {
250 defedge = Max(UVDEFLECTION, defedge);
251 myMapdefle.Bind(aEdge, defedge);
252 }
ceb418e1 253 }
254 else
255 {
81093856 256 if (!myMapdefle.IsBound(aEdge))
ceb418e1 257 {
81093856 258 myMapdefle.Bind(aEdge, defedge);
7fd59977 259 }
7fd59977 260 }
ceb418e1 261
262 Standard_Real aFirstParam, aLastParam;
263 Handle(Geom2d_Curve) aCurve2d =
264 BRep_Tool::CurveOnSurface(aEdge, aFace, aFirstParam, aLastParam);
265
266 if (aCurve2d.IsNull())
267 continue;
81093856 268 Handle(Geom2dAdaptor_HCurve) aPCurve =
269 new Geom2dAdaptor_HCurve(aCurve2d, aFirstParam, aLastParam);
ceb418e1 270
271 add(aEdge, aPCurve, defedge);
e71669c6 272 myParameters.Angle = savangle;
7fd59977 273 }
7fd59977 274 }
7fd59977 275
2caff0b3 276 if ( nbEdge == 0 || aVertexEdgeMap->Extent() < 3 )
ceb418e1 277 {
2caff0b3 278 myAttribute->ChangeStructure().Nullify();
ceb418e1 279 myAttribute->SetStatus(BRepMesh_Failure);
280 return myAttribute->GetStatus();
281 }
7fd59977 282
e71669c6 283 if ( myParameters.Relative )
ceb418e1 284 {
285 defface = defface / nbEdge;
7fd59977 286 }
ceb418e1 287 else
288 {
e71669c6 289 defface = myParameters.Deflection;
ceb418e1 290 }
291
e71669c6 292 defface = Max(maxdef, defface);
ceb418e1 293
294 TopLoc_Location aLoc;
295 Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation(aFace, aLoc);
e1c1b6b9 296 const Handle(BRepAdaptor_HSurface)& gFace = myAttribute->Surface();
ceb418e1 297
e71669c6 298 if ( aTriangulation.IsNull() )
7fd59977 299 {
ceb418e1 300 Standard_Real xCur, yCur;
301 Standard_Real maxX, minX, maxY, minY;
302
303 minX = minY = 1.e100;
304 maxX = maxY =-1.e100;
305
306 Standard_Integer ipn = 0;
307 Standard_Integer i1 = 1;
2caff0b3 308 for ( i1 = 1; i1 <= aVertexEdgeMap->Extent(); ++i1 )
7fd59977 309 {
2caff0b3 310 const BRepMesh_Vertex& aVertex =
311 myAttribute->ChangeStructure()->GetNode(aVertexEdgeMap->FindKey(i1));
ceb418e1 312
313 ++ipn;
314
315 xCur = aVertex.Coord().X();
316 yCur = aVertex.Coord().Y();
317
318 minX = Min(xCur, minX);
319 maxX = Max(xCur, maxX);
320 minY = Min(yCur, minY);
321 maxY = Max(yCur, maxY);
7fd59977 322 }
ceb418e1 323
324 Standard_Real myumin = minX;
325 Standard_Real myumax = maxX;
326 Standard_Real myvmin = minY;
327 Standard_Real myvmax = maxY;
328
329 const Standard_Real umin = gFace->FirstUParameter();
330 const Standard_Real umax = gFace->LastUParameter();
331 const Standard_Real vmin = gFace->FirstVParameter();
332 const Standard_Real vmax = gFace->LastVParameter();
333
334 if (myumin < umin || myumax > umax)
7fd59977 335 {
ceb418e1 336 if (gFace->IsUPeriodic())
337 {
338 if ((myumax - myumin) > (umax - umin))
339 myumax = myumin + (umax - umin);
340 }
341 else
342 {
343 if (umin > myumin)
344 myumin = umin;
345
346 if (umax < myumax)
347 myumax = umax;
348 }
7fd59977 349 }
7fd59977 350
ceb418e1 351 if (myvmin < vmin || myvmax > vmax)
7fd59977 352 {
ceb418e1 353 if (gFace->IsVPeriodic())
354 {
355 if ((myvmax - myvmin) > (vmax - vmin))
356 myvmax = myvmin + (vmax - vmin);
357 }
358 else
7fd59977 359 {
ceb418e1 360 if ( vmin > myvmin )
361 myvmin = vmin;
362
363 if (vmax < myvmax)
364 myvmax = vmax;
7fd59977 365 }
366 }
ceb418e1 367
368 GeomAbs_SurfaceType aSurfType = gFace->GetType();
369 // Fast verification of the validity of calculated limits.
370 // If wrong, sure a problem of pcurve.
371 if (aSurfType == GeomAbs_BezierSurface &&
372 (myumin < -0.5 || myumax > 1.5 || myvmin < -0.5 || myvmax > 1.5) )
7fd59977 373 {
2caff0b3 374 myAttribute->ChangeStructure().Nullify();
ceb418e1 375 myAttribute->SetStatus(BRepMesh_Failure);
376 return myAttribute->GetStatus();
7fd59977 377 }
7fd59977 378
ceb418e1 379 //define parameters for correct parametrics
380 Standard_Real deltaX = 1.0;
381 Standard_Real deltaY = 1.0;
382
7fd59977 383 {
71316196 384 Standard_Real aTolU, aTolV;
385 myAttribute->ChangeStructure()->Data()->GetTolerance(aTolU, aTolV);
386 const Standard_Real aTol = Sqrt(aTolU * aTolU + aTolV * aTolV);
387
848fa7e3 388 BRepMesh::HClassifier& aClassifier = myAttribute->ChangeClassifier();
71316196 389 BRepMesh_WireChecker aDFaceChecker(aFace, aTol, aInternalEdges,
390 aVertexEdgeMap, myAttribute->ChangeStructure(),
e71669c6 391 myumin, myumax, myvmin, myvmax, myParameters.InParallel );
ceb418e1 392
393 aDFaceChecker.ReCompute(aClassifier);
394 BRepMesh_Status aCheckStatus = aDFaceChecker.Status();
395
396 if (aCheckStatus == BRepMesh_SelfIntersectingWire)
7fd59977 397 {
ceb418e1 398 Standard_Integer nbmaill = 0;
399 Standard_Real eps = Precision::Confusion();
400 while (nbmaill < 5 && aCheckStatus != BRepMesh_ReMesh)
7fd59977 401 {
ceb418e1 402 ++nbmaill;
403
2caff0b3 404 resetDataStructure();
ceb418e1 405
e1c1b6b9 406 for (TopoDS_Iterator aWireIt(aFace); aWireIt.More(); aWireIt.Next())
407 {
408 for (TopoDS_Iterator aEdgeIt(aWireIt.Value()); aEdgeIt.More(); aEdgeIt.Next(), ++nbEdge)
409 {
410 const TopoDS_Edge& anEdge = TopoDS::Edge(aEdgeIt.Value());
411 if (anEdge.IsNull())
412 continue;
413 if (myEdges.IsBound(anEdge))
414 myEdges.UnBind(anEdge);
415
416 defedge = Max(myMapdefle(anEdge) / 3.0, eps);
417 myMapdefle.Bind(anEdge, defedge);
418
419 Standard_Real aFirstParam, aLastParam;
420 Handle(Geom2d_Curve) aCurve2d =
421 BRep_Tool::CurveOnSurface(anEdge, aFace, aFirstParam, aLastParam);
422 if (aCurve2d.IsNull())
423 continue;
424
81093856 425 Handle(Geom2dAdaptor_HCurve) aPCurve =
426 new Geom2dAdaptor_HCurve(aCurve2d, aFirstParam, aLastParam);
e1c1b6b9 427 add(anEdge, aPCurve, defedge);
428 }
01a6e62b 429 }
7fd59977 430
ceb418e1 431 aDFaceChecker.ReCompute(aClassifier);
432 if (aDFaceChecker.Status() == BRepMesh_NoError)
433 aCheckStatus = BRepMesh_ReMesh;
01a6e62b 434 }
703a6abd 435 }
ceb418e1 436
437 myAttribute->SetStatus(aCheckStatus);
438 if (!myAttribute->IsValid())
2caff0b3 439 {
440 myAttribute->ChangeStructure().Nullify();
ceb418e1 441 return myAttribute->GetStatus();
2caff0b3 442 }
7fd59977 443 }
7fd59977 444
ceb418e1 445 // try to find the real length:
446 // akm (bug OCC16) : We must calculate these measures in non-singular
447 // parts of face. Let's try to compute average value of three
448 // (umin, (umin+umax)/2, umax), and respectively for v.
449 // vvvvv
450 Standard_Real longu = 0.0, longv = 0.0; //, last , first;
451 gp_Pnt P11, P12, P21, P22, P31, P32;
452
453 Standard_Real du = 0.05 * ( myumax - myumin );
454 Standard_Real dv = 0.05 * ( myvmax - myvmin );
455 Standard_Real dfuave = 0.5 * ( myumin + myumax );
456 Standard_Real dfvave = 0.5 * ( myvmin + myvmax );
457 Standard_Real dfucur, dfvcur;
458
459 // U loop
460 gFace->D0(myumin, myvmin, P11);
461 gFace->D0(myumin, dfvave, P21);
462 gFace->D0(myumin, myvmax, P31);
463 for (i1=1, dfucur=myumin+du; i1 <= 20; i1++, dfucur+=du)
464 {
465 gFace->D0(dfucur, myvmin, P12);
466 gFace->D0(dfucur, dfvave, P22);
467 gFace->D0(dfucur, myvmax, P32);
468 longu += ( P11.Distance(P12) + P21.Distance(P22) + P31.Distance(P32) );
469 P11 = P12;
470 P21 = P22;
471 P31 = P32;
472 }
7fd59977 473
ceb418e1 474 // V loop
475 gFace->D0(myumin, myvmin, P11);
476 gFace->D0(dfuave, myvmin, P21);
477 gFace->D0(myumax, myvmin, P31);
478 for (i1=1, dfvcur=myvmin+dv; i1 <= 20; i1++, dfvcur+=dv)
479 {
480 gFace->D0(myumin, dfvcur, P12);
481 gFace->D0(dfuave, dfvcur, P22);
482 gFace->D0(myumax, dfvcur, P32);
483 longv += ( P11.Distance(P12) + P21.Distance(P22) + P31.Distance(P32) );
484 P11 = P12;
485 P21 = P22;
486 P31 = P32;
7fd59977 487 }
ceb418e1 488
489 longu /= 3.;
490 longv /= 3.;
491 // akm (bug OCC16) ^^^^^
492
493 if (longu <= 1.e-16 || longv <= 1.e-16)
494 {
495 //yes, it is seen!!
2caff0b3 496 myAttribute->ChangeStructure().Nullify();
ceb418e1 497 myAttribute->SetStatus(BRepMesh_Failure);
498 return myAttribute->GetStatus();
499 }
500
501
502 if (aSurfType == GeomAbs_Torus)
503 {
504 gp_Torus Tor = gFace->Torus();
505 Standard_Real r = Tor.MinorRadius(), R = Tor.MajorRadius();
506 Standard_Real Du, Dv;//, pasu, pasv;
507
508 Dv = Max(1.0e0 - (defface/r),0.0e0) ;
509 Standard_Real oldDv = 2.0 * ACos (Dv);
e71669c6 510 oldDv = Min(oldDv, myParameters.Angle);
ceb418e1 511 Dv = 0.9*oldDv; //TWOTHIRD * oldDv;
512 Dv = oldDv;
513
514 Standard_Integer nbV = Max((Standard_Integer)((myvmax-myvmin)/Dv), 2);
515 Dv = (myvmax-myvmin)/(nbV+1);
516
517 Standard_Real ru = R + r;
518 if ( ru > 1.e-16 )
519 {
520 Du = Max(1.0e0 - (defface/ru),0.0e0);
521 Du = (2.0 * ACos (Du));
e71669c6 522 Du = Min(Du, myParameters.Angle);
ceb418e1 523 Standard_Real aa = sqrt(Du*Du + oldDv*oldDv);
524
525 if (aa < gp::Resolution())
2caff0b3 526 {
527 myAttribute->ChangeStructure().Nullify();
ceb418e1 528 return myAttribute->GetStatus();
2caff0b3 529 }
ceb418e1 530
531 Du = Du * Min(oldDv, Du) / aa;
532 }
533 else
534 {
535 Du = Dv;
536 }
537
538 Standard_Integer nbU = Max((Standard_Integer)((myumax-myumin)/Du), 2);
539 nbU = Max(nbU, (Standard_Integer)(nbV*(myumax-myumin)*R/((myvmax-myvmin)*r)/5.));
7fd59977 540
ceb418e1 541 Du = (myumax-myumin)/(nbU+1);
542 //-- DeltaX and DeltaY are chosen so that to avoid "jumping"
543 //-- of points on the grid
544 deltaX = Du;
545 deltaY = Dv;
546 }
547 else if (aSurfType == GeomAbs_Cylinder)
548 {
549 gp_Cylinder Cyl = gFace->Cylinder();
550 Standard_Real R = Cyl.Radius();
7fd59977 551
ceb418e1 552 // Calculate parameters for iteration in U direction
553 Standard_Real Du = 1.0 - (defface/R);
554 if (Du < 0.0)
555 Du = 0.0;
7fd59977 556
ceb418e1 557 Du = 2.0 * ACos (Du);
e71669c6 558 if (Du > myParameters.Angle)
559 Du = myParameters.Angle;
7fd59977 560
ceb418e1 561 deltaX = Du / longv;
562 deltaY = 1.;
563 }
7fd59977 564 else
ceb418e1 565 {
566 deltaX = (myumax-myumin)/longu;
567 deltaY = (myvmax-myvmin)/longv;
568 }
7fd59977 569
ceb418e1 570 // Restore face attribute
571 myAttribute->SetDefFace(defface);
572 myAttribute->SetUMax(myumax);
573 myAttribute->SetVMax(myvmax);
574 myAttribute->SetUMin(myumin);
575 myAttribute->SetVMin(myvmin);
576 myAttribute->SetDeltaX(deltaX);
577 myAttribute->SetDeltaY(deltaY);
578 }
0a2a7b46 579
580 myAttribute->ChangeMeshNodes() =
581 myAttribute->ChangeStructure()->Data()->Vertices();
7fd59977 582 }
583 catch(Standard_Failure)
584 {
ceb418e1 585 myAttribute->SetStatus(BRepMesh_Failure);
7fd59977 586 }
ceb418e1 587
2caff0b3 588 myAttribute->ChangeStructure().Nullify();
589 return myAttribute->GetStatus();
0d36f7e4
O
590}
591
7fd59977 592//=======================================================================
ceb418e1 593//function : getEdgeAttributes
594//purpose :
7fd59977 595//=======================================================================
ceb418e1 596Standard_Boolean BRepMesh_FastDiscret::getEdgeAttributes(
597 const TopoDS_Edge& theEdge,
81093856 598 const Handle(Geom2dAdaptor_HCurve)& thePCurve,
ceb418e1 599 const Standard_Real theDefEdge,
600 BRepMesh_FastDiscret::EdgeAttributes& theAttributes) const
7fd59977 601{
ceb418e1 602 EdgeAttributes& aEAttr = theAttributes;
7fd59977 603
ceb418e1 604 // Get vertices
605 TopExp::Vertices(theEdge, aEAttr.FirstVertex, aEAttr.LastVertex);
606 if (aEAttr.FirstVertex.IsNull() || aEAttr.LastVertex.IsNull())
607 return Standard_False;
7fd59977 608
ceb418e1 609 // Get range on 2d curve
610 const TopoDS_Face& aFace = myAttribute->Face();
611 BRep_Tool::Range(theEdge, aFace, aEAttr.FirstParam, aEAttr.LastParam);
7fd59977 612
ceb418e1 613 // Get end points on 2d curve
614 BRep_Tool::UVPoints(theEdge, aFace, aEAttr.FirstUV, aEAttr.LastUV);
7fd59977 615
ceb418e1 616 aEAttr.IsSameUV =
617 aEAttr.FirstUV.IsEqual(aEAttr.LastUV, Precision::PConfusion());
ceb418e1 618 if (aEAttr.IsSameUV)
7fd59977 619 {
620 // 1. is it really sameUV without being degenerated
621 gp_Pnt2d uvF, uvL;
81093856 622 thePCurve->D0(thePCurve->FirstParameter(), uvF);
623 thePCurve->D0(thePCurve->LastParameter(), uvL);
ceb418e1 624
625 if (!aEAttr.FirstUV.IsEqual(uvF, Precision::PConfusion()))
626 aEAttr.FirstUV = uvF;
627
628 if (!aEAttr.LastUV.IsEqual(uvL, Precision::PConfusion()))
629 aEAttr.LastUV = uvL;
81093856 630
631 aEAttr.IsSameUV =
632 aEAttr.FirstUV.IsEqual(aEAttr.LastUV, Precision::PConfusion());
7fd59977 633 }
634
81093856 635 //Control tolerance of vertices
636 const Handle(BRepAdaptor_HSurface)& gFace = myAttribute->Surface();
637 gp_Pnt pFirst = gFace->Value(aEAttr.FirstUV.X(), aEAttr.FirstUV.Y());
638 gp_Pnt pLast = gFace->Value(aEAttr.LastUV.X(), aEAttr.LastUV.Y());
639
640 Standard_Real aSqDist = pFirst.SquareDistance(BRep_Tool::Pnt(aEAttr.FirstVertex));
641 aSqDist = Max(aSqDist, pLast.SquareDistance(BRep_Tool::Pnt(aEAttr.LastVertex)));
642
643 aEAttr.Deflection = Max(theDefEdge, BRep_Tool::Tolerance(theEdge));
644 aEAttr.Deflection = Max(aEAttr.Deflection, sqrt(aSqDist));
645
ceb418e1 646 return Standard_True;
647}
7fd59977 648
ceb418e1 649//=======================================================================
650//function : registerEdgeVertices
651//purpose :
652//=======================================================================
653void BRepMesh_FastDiscret::registerEdgeVertices(
654 BRepMesh_FastDiscret::EdgeAttributes& theAttributes,
655 Standard_Integer& ipf,
656 Standard_Integer& ivf,
657 Standard_Integer& isvf,
658 Standard_Integer& ipl,
659 Standard_Integer& ivl,
660 Standard_Integer& isvl)
661{
662 EdgeAttributes& aEAttr = theAttributes;
663 if (aEAttr.FirstVExtractor.IsNull())
7fd59977 664 {
ceb418e1 665 // Use edge geometry to produce tesselation.
666 aEAttr.FirstVExtractor =
667 new TopoDSVExplorer(aEAttr.FirstVertex, aEAttr.IsSameUV, aEAttr.LastVertex);
7fd59977 668 }
ceb418e1 669
670 if (aEAttr.LastVExtractor.IsNull())
7fd59977 671 {
ceb418e1 672 // Use edge geometry to produce tesselation.
673 aEAttr.LastVExtractor =
674 new TopoDSVExplorer(aEAttr.LastVertex, aEAttr.IsSameUV, aEAttr.FirstVertex);
7fd59977 675 }
b62b93ac 676
ceb418e1 677 // Process first vertex
678 ipf = myAttribute->GetVertexIndex(aEAttr.FirstVExtractor, Standard_True);
81093856 679 Standard_Real aMinDist = 2. * BRep_Tool::Tolerance(aEAttr.FirstVertex);
680 gp_XY aTmpUV1 = BRepMesh_ShapeTool::FindUV(ipf, aEAttr.FirstUV, aMinDist, myAttribute);
b62b93ac 681
81093856 682 myAttribute->AddNode(ipf, aTmpUV1, BRepMesh_Frontier, ivf, isvf);
7fd59977 683
684 // Process last vertex
ceb418e1 685 ipl = aEAttr.LastVertex.IsSame(aEAttr.FirstVertex) ? ipf :
686 myAttribute->GetVertexIndex(aEAttr.LastVExtractor, Standard_True);
81093856 687 aMinDist = 2. * BRep_Tool::Tolerance(aEAttr.LastVertex);
688 gp_XY aTmpUV2 = BRepMesh_ShapeTool::FindUV(ipl, aEAttr.LastUV, aMinDist, myAttribute);
689
690 myAttribute->AddNode(ipl, aTmpUV2, BRepMesh_Frontier, ivl, isvl);
ceb418e1 691
81093856 692 // Update edge deflection
693 const Handle(BRepAdaptor_HSurface)& gFace = myAttribute->Surface();
694 gp_Pnt aPntE1 = gFace->Value(aEAttr.FirstUV.X(), aEAttr.FirstUV.Y());
695 gp_Pnt aPntFound1 = gFace->Value(aTmpUV1.X(), aTmpUV1.Y());
696 Standard_Real aSqDist = aPntE1.SquareDistance(aPntFound1);
697 gp_Pnt aPntE2 = gFace->Value(aEAttr.LastUV.X(), aEAttr.LastUV.Y());
698 gp_Pnt aPntFound2 = gFace->Value(aTmpUV2.X(), aTmpUV2.Y());
699 aSqDist = Max(aSqDist, aPntE2.SquareDistance(aPntFound2));
700 aEAttr.Deflection = Max(aEAttr.Deflection, sqrt(aSqDist));
ceb418e1 701}
702
703//=======================================================================
704//function : add
705//purpose :
706//=======================================================================
707void BRepMesh_FastDiscret::add(
708 const TopoDS_Edge& theEdge,
81093856 709 const Handle(Geom2dAdaptor_HCurve)& thePCurve,
ceb418e1 710 const Standard_Real theDefEdge)
711{
712 const TopAbs_Orientation orEdge = theEdge.Orientation();
713 if (orEdge == TopAbs_EXTERNAL)
714 return;
715
716 EdgeAttributes aEAttr;
717 if (!getEdgeAttributes(theEdge, thePCurve, theDefEdge, aEAttr))
718 return;
719
720 if (!myEdges.IsBound(theEdge))
7fd59977 721 {
81093856 722 update(theEdge, thePCurve, theDefEdge, aEAttr);
ceb418e1 723 return;
7fd59977 724 }
b62b93ac 725
ceb418e1 726 Standard_Integer ipf, ivf, isvf, ipl, ivl, isvl;
727 registerEdgeVertices(aEAttr, ipf, ivf, isvf, ipl, ivl, isvl);
b62b93ac 728
ceb418e1 729 // If this Edge has been already checked and it is not degenerated,
730 // the points of the polygon calculated at the first check are retrieved :
7fd59977 731
ceb418e1 732 // retrieve the polygone:
733 const BRepMesh_PairOfPolygon& aPair = myEdges.Find(theEdge);
734 const Handle(Poly_PolygonOnTriangulation)& aPolygon = aPair.First();
735 const TColStd_Array1OfInteger& aNodes = aPolygon->Nodes();
736 Handle(TColStd_HArray1OfReal) aParams = aPolygon->Parameters();
7fd59977 737
ceb418e1 738 // creation anew:
739 const Standard_Integer aNodesNb = aNodes.Length();
740 TColStd_Array1OfInteger aNewNodes (1, aNodesNb);
741 TColStd_Array1OfReal aNewParams(1, aNodesNb);
7fd59977 742
ceb418e1 743 aNewNodes (1) = isvf;
744 aNewParams(1) = aEAttr.FirstParam;
7fd59977 745
ceb418e1 746 aNewNodes (aNodesNb) = isvl;
747 aNewParams(aNodesNb) = aEAttr.LastParam;
7fd59977 748
ceb418e1 749 const TopoDS_Face& aFace = myAttribute->Face();
750 if (!BRepMesh_ShapeTool::IsDegenerated(theEdge, aFace))
751 {
752 BRepMesh_EdgeParameterProvider aProvider(theEdge, aFace, aParams);
753 for (Standard_Integer i = 2; i < aNodesNb; ++i)
7fd59977 754 {
ceb418e1 755 const Standard_Integer aPointId = aNodes(i);
848fa7e3 756 const gp_Pnt& aPnt = myBoundaryPoints->Find(aPointId);
7fd59977 757
ceb418e1 758 const Standard_Real aParam = aProvider.Parameter(i, aPnt);
81093856 759 gp_Pnt2d aUV = thePCurve->Value(aParam);
32d878f5 760
ceb418e1 761 Standard_Integer iv2, isv;
762 myAttribute->AddNode(aPointId, aUV.Coord(), BRepMesh_OnCurve, iv2, isv);
32d878f5 763
ceb418e1 764 aNewNodes (i) = isv;
765 aNewParams(i) = aParam;
ceb418e1 766 }
ceb418e1 767 }
7fd59977 768
ceb418e1 769 Handle(Poly_PolygonOnTriangulation) P1 =
770 new Poly_PolygonOnTriangulation(aNewNodes, aNewParams);
7fd59977 771
81093856 772 storePolygon(theEdge, P1, aEAttr.Deflection);
ceb418e1 773}
0d36f7e4 774
ceb418e1 775//=======================================================================
776//function : update(edge)
777//purpose :
778//=======================================================================
779void BRepMesh_FastDiscret::update(
780 const TopoDS_Edge& theEdge,
81093856 781 const Handle(Geom2dAdaptor_HCurve)& theC2d,
ceb418e1 782 const Standard_Real theDefEdge,
783 BRepMesh_FastDiscret::EdgeAttributes& theAttributes)
784{
785 EdgeAttributes& aEAttr = theAttributes;
7fd59977 786
ceb418e1 787 const TopoDS_Face& aFace = myAttribute->Face();
788 Handle(BRepMesh_IEdgeTool) aEdgeTool;
789 // Try to find existing tessellation.
790 for (Standard_Integer i = 1; aEdgeTool.IsNull(); ++i)
791 {
792 TopLoc_Location aLoc;
793 Handle(Poly_Triangulation) aTriangulation;
794 Handle(Poly_PolygonOnTriangulation) aPolygon;
795 BRep_Tool::PolygonOnTriangulation(theEdge, aPolygon, aTriangulation, aLoc, i);
7fd59977 796
ceb418e1 797 if (aPolygon.IsNull())
798 break;
7fd59977 799
ceb418e1 800 if (aTriangulation.IsNull() || !aPolygon->HasParameters())
801 continue;
7fd59977 802
ceb418e1 803 if (aPolygon->Deflection() > 1.1 * theDefEdge)
804 continue;
7fd59977 805
ceb418e1 806 const TColgp_Array1OfPnt& aNodes = aTriangulation->Nodes();
807 const TColStd_Array1OfInteger& aIndices = aPolygon->Nodes();
808 Handle(TColStd_HArray1OfReal) aParams = aPolygon->Parameters();
7fd59977 809
ceb418e1 810 aEAttr.FirstVExtractor = new PolyVExplorer(aEAttr.FirstVertex,
811 aEAttr.IsSameUV, aEAttr.LastVertex, aIndices(1), aNodes, aLoc);
7fd59977 812
ceb418e1 813 aEAttr.LastVExtractor = new PolyVExplorer(aEAttr.LastVertex,
814 aEAttr.IsSameUV, aEAttr.FirstVertex, aIndices(aIndices.Length()), aNodes, aLoc);
7fd59977 815
ceb418e1 816 aEdgeTool = new BRepMesh_EdgeTessellationExtractor(theEdge, theC2d,
817 aFace, aTriangulation, aPolygon, aLoc);
7fd59977 818 }
ceb418e1 819
820 if (aEdgeTool.IsNull())
7fd59977 821 {
ceb418e1 822 aEdgeTool = new BRepMesh_EdgeTessellator(theEdge, myAttribute,
e71669c6 823 mySharedFaces, theDefEdge, myParameters.Angle, myParameters.MinSize);
7fd59977 824 }
7fd59977 825
ceb418e1 826 Standard_Integer ipf, ivf, isvf, ipl, ivl, isvl;
827 registerEdgeVertices(aEAttr, ipf, ivf, isvf, ipl, ivl, isvl);
7fd59977 828
ceb418e1 829 Handle(Poly_PolygonOnTriangulation) P1, P2;
830 if (BRepMesh_ShapeTool::IsDegenerated(theEdge, aFace))
7fd59977 831 {
e1c1b6b9 832 // two nodes
833 Standard_Integer aNewNodesArr[] = {isvf, isvl};
834 Standard_Integer aNewNodInStructArr[] = {ipf, ipl};
835 Standard_Real aNewParamsArr[] = {aEAttr.FirstParam, aEAttr.LastParam};
836 TColStd_Array1OfInteger aNewNodes (aNewNodesArr[0], 1, 2);
837 TColStd_Array1OfInteger aNewNodInStruct(aNewNodInStructArr[0], 1, 2);
838 TColStd_Array1OfReal aNewParams (aNewParamsArr[0], 1, 2);
7fd59977 839
ceb418e1 840 P1 = new Poly_PolygonOnTriangulation(aNewNodes, aNewParams);
841 P2 = new Poly_PolygonOnTriangulation(aNewNodInStruct, aNewParams);
842 }
843 else
844 {
845 const Standard_Integer aNodesNb = aEdgeTool->NbPoints();
e1c1b6b9 846 // Allocate the memory for arrays aNewNodesVec, aNewNodesInStructVec, aNewParamsVec
847 // only once using the buffer aBuf.
848 TColStd_Array1OfCharacter aBuf(1, aNodesNb * (2*sizeof(Standard_Integer) + sizeof(Standard_Real)));
849 TColStd_Array1OfInteger aNewNodesVec(*reinterpret_cast<const Standard_Integer*>
850 (&aBuf(1)), 1, aNodesNb);
851 TColStd_Array1OfInteger aNewNodesInStructVec(*reinterpret_cast<const Standard_Integer*>
852 (&aBuf(1 + aNodesNb*sizeof(Standard_Integer))), 1, aNodesNb);
853 TColStd_Array1OfReal aNewParamsVec(*reinterpret_cast<const Standard_Real*>
854 (&aBuf(1 + aNodesNb*2*sizeof(Standard_Integer))), 1, aNodesNb);
7fd59977 855
660b601e 856 Standard_Integer aNodesCount = 1;
857 aNewNodesInStructVec(aNodesCount) = ipf;
858 aNewNodesVec (aNodesCount) = isvf;
859 aNewParamsVec (aNodesCount) = aEAttr.FirstParam;
7fd59977 860
660b601e 861 ++aNodesCount;
dfb3bdd4 862 Standard_Integer aPrevNodeId = ivf;
ceb418e1 863 Standard_Integer aLastPointId = myAttribute->LastPointId();
864 for (Standard_Integer i = 2; i < aNodesNb; ++i)
865 {
866 gp_Pnt aPnt;
867 gp_Pnt2d aUV;
868 Standard_Real aParam;
660b601e 869 if (!aEdgeTool->Value(i, aParam, aPnt, aUV))
870 continue;
871
dfb3bdd4 872 // Imitate index of 3d point in order to not to add points to map without necessity.
ceb418e1 873 Standard_Integer iv2, isv;
dfb3bdd4 874 myAttribute->AddNode(aLastPointId + 1, aUV.Coord(), BRepMesh_Frontier, iv2, isv);
875 if (aPrevNodeId == iv2)
876 continue;
877
878 // Ok, now we can add point to the map.
879 myBoundaryPoints->Bind (++aLastPointId, aPnt);
7fd59977 880
660b601e 881 aNewNodesInStructVec(aNodesCount) = aLastPointId;
882 aNewNodesVec (aNodesCount) = isv;
883 aNewParamsVec (aNodesCount) = aParam;
dfb3bdd4 884
660b601e 885 ++aNodesCount;
dfb3bdd4 886 aPrevNodeId = iv2;
ceb418e1 887 }
7fd59977 888
660b601e 889 aNewNodesInStructVec(aNodesCount) = ipl;
890 aNewNodesVec (aNodesCount) = isvl;
891 aNewParamsVec (aNodesCount) = aEAttr.LastParam;
892
893 TColStd_Array1OfInteger aNewNodes (aNewNodesVec.First (), 1, aNodesCount);
894 TColStd_Array1OfInteger aNewNodInStruct(aNewNodesInStructVec.First(), 1, aNodesCount);
895 TColStd_Array1OfReal aNewParams (aNewParamsVec.First(), 1, aNodesCount);
896
ceb418e1 897 P1 = new Poly_PolygonOnTriangulation(aNewNodes, aNewParams);
898 P2 = new Poly_PolygonOnTriangulation(aNewNodInStruct, aNewParams);
899 }
7fd59977 900
81093856 901 storePolygon(theEdge, P1, aEAttr.Deflection);
902 storePolygonSharedData(theEdge, P2, aEAttr.Deflection);
7fd59977 903}
904
905//=======================================================================
ceb418e1 906//function : storeInternalPolygon
7fd59977 907//purpose :
908//=======================================================================
ceb418e1 909void BRepMesh_FastDiscret::storePolygon(
910 const TopoDS_Edge& theEdge,
911 Handle(Poly_PolygonOnTriangulation)& thePolygon,
912 const Standard_Real theDeflection)
7fd59977 913{
ceb418e1 914 thePolygon->Deflection(theDeflection);
2caff0b3 915 BRepMesh::HDMapOfShapePairOfPolygon& aInternalEdges = myAttribute->ChangeInternalEdges();
916 if (aInternalEdges->IsBound(theEdge))
ceb418e1 917 {
2caff0b3 918 BRepMesh_PairOfPolygon& aPair = aInternalEdges->ChangeFind(theEdge);
ceb418e1 919 if (theEdge.Orientation() == TopAbs_REVERSED)
920 aPair.Append(thePolygon);
921 else
922 aPair.Prepend(thePolygon);
7fd59977 923
ceb418e1 924 return;
925 }
7fd59977 926
ceb418e1 927 BRepMesh_PairOfPolygon aPair;
928 aPair.Append(thePolygon);
2caff0b3 929 aInternalEdges->Bind(theEdge, aPair);
7fd59977 930}
931
932//=======================================================================
ceb418e1 933//function : storePolygonSharedData
7fd59977 934//purpose :
935//=======================================================================
ceb418e1 936void BRepMesh_FastDiscret::storePolygonSharedData(
937 const TopoDS_Edge& theEdge,
938 Handle(Poly_PolygonOnTriangulation)& thePolygon,
939 const Standard_Real theDeflection)
7fd59977 940{
ceb418e1 941 thePolygon->Deflection(theDeflection);
942 BRepMesh_PairOfPolygon aPair;
943 aPair.Append(thePolygon);
944 myEdges.Bind(theEdge, aPair);
7fd59977 945}
946
947//=======================================================================
948//function : GetFaceAttribute
949//purpose :
950//=======================================================================
ceb418e1 951Standard_Boolean BRepMesh_FastDiscret::GetFaceAttribute(
952 const TopoDS_Face& theFace,
0a2a7b46 953 Handle(BRepMesh_FaceAttribute)& theAttribute,
954 const Standard_Boolean isForceCreate) const
7fd59977 955{
ceb418e1 956 if (myAttributes.IsBound(theFace))
7fd59977 957 {
ceb418e1 958 theAttribute = myAttributes(theFace);
7fd59977 959 return Standard_True;
960 }
0a2a7b46 961 else if (isForceCreate)
962 {
963 theAttribute = new BRepMesh_FaceAttribute(myBoundaryVertices, myBoundaryPoints);
964 myAttributes.Bind(theFace, theAttribute);
965 }
ceb418e1 966
7fd59977 967 return Standard_False;
968}
969
970//=======================================================================
971//function : RemoveFaceAttribute
972//purpose :
973//=======================================================================
7fd59977 974void BRepMesh_FastDiscret::RemoveFaceAttribute(const TopoDS_Face& theFace)
975{
ceb418e1 976 if (myAttributes.IsBound(theFace))
977 myAttributes.UnBind(theFace);
973c2be1 978}