0023024: Update headers of OCCT files
[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
4// Copyright (c) 1999-2012 OPEN CASCADE SAS
5//
6// The content of this file is subject to the Open CASCADE Technology Public
7// License Version 6.5 (the "License"). You may not use the content of this file
8// except in compliance with the License. Please obtain a copy of the License
9// at http://www.opencascade.org and read it completely before using this file.
10//
11// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13//
14// The Original Code and all software distributed under the License is
15// distributed on an "AS IS" basis, without warranty of any kind, and the
16// Initial Developer hereby disclaims all such warranties, including without
17// limitation, any warranties of merchantability, fitness for a particular
18// purpose or non-infringement. Please see the License for the specific terms
19// and conditions governing the rights and limitations under the License.
20
7fd59977 21
22#include <BRepMesh_FastDiscret.ixx>
23
24#include <BRepMesh_FastDiscretFace.hxx>
25#include <BRepMesh_FaceAttribute.hxx>
26#include <BRepMesh_DataStructureOfDelaun.hxx>
27#include <BRepMesh_ClassifierPtr.hxx>
28#include <BRepMesh_GeomTool.hxx>
29#include <BRepMesh_PairOfPolygon.hxx>
30#include <BRepMesh_DataMapOfShapePairOfPolygon.hxx>
31#include <BRepMesh_DataMapIteratorOfDataMapOfShapePairOfPolygon.hxx>
0d36f7e4 32#include <Geom_Plane.hxx>
7fd59977 33#include <GeomAbs_IsoType.hxx>
34#include <GeomAbs_SurfaceType.hxx>
35#include <TopAbs.hxx>
36#include <TColStd_HArray1OfReal.hxx>
37#include <Precision.hxx>
38
39#include <BRep_Builder.hxx>
40#include <BRep_Tool.hxx>
41#include <Poly_Triangulation.hxx>
42#include <Poly_PolygonOnTriangulation.hxx>
43#include <Poly_Connect.hxx>
44#include <TColStd_SequenceOfInteger.hxx>
45#include <TColStd_Array1OfInteger.hxx>
46#include <TColStd_HArray1OfInteger.hxx>
47
48#include <TColgp_Array1OfPnt.hxx>
49#include <TColgp_Array1OfPnt2d.hxx>
50#include <Precision.hxx>
51
52#include <BRepAdaptor_Curve.hxx>
53#include <BRepAdaptor_Surface.hxx>
54#include <BRepAdaptor_HSurface.hxx>
55#include <BRepTools.hxx>
56#include <BndLib_Add3dCurve.hxx>
57#include <BRepBndLib.hxx>
58#include <Bnd_Box.hxx>
59#include <TopoDS.hxx>
60#include <TopExp.hxx>
61#include <TopExp_Explorer.hxx>
62
63#include <Geom2d_Curve.hxx>
64
65#include <TColStd_DataMapOfIntegerInteger.hxx>
66#include <BRepMesh_ShapeTool.hxx>
67#include <ElSLib.hxx>
68#include <Geom_Surface.hxx>
69#include <Adaptor3d_IsoCurve.hxx>
70#include <BRepMesh_IndexedMapOfVertex.hxx>
71#include <Extrema_LocateExtPC.hxx>
72
73#include <BRepMesh_ListOfXY.hxx>
74#include <BRepMesh_ListIteratorOfListOfXY.hxx>
75
76#include <TColStd_Array1OfInteger.hxx>
77#include <BRepMesh_IDMapOfNodeOfDataStructureOfDelaun.hxx>
78#include <Standard_ErrorHandler.hxx>
79#include <Standard_Failure.hxx>
80//#include <TColStd_DataMapOfInteger.hxx>
81#include <TColGeom2d_SequenceOfCurve.hxx>
82#include <TopTools_SequenceOfShape.hxx>
83#include <NCollection_IncAllocator.hxx>
84
85#include <BRep_ListIteratorOfListOfPointRepresentation.hxx>
86#include <BRep_PointRepresentation.hxx>
87#include <BRep_TVertex.hxx>
88#include <TColStd_MapOfInteger.hxx>
89#include <SortTools_ShellSortOfReal.hxx>
90#include <TCollection_CompareOfReal.hxx>
91
92#include <TopTools_HArray1OfShape.hxx>
93#include <TopTools_ListIteratorOfListOfShape.hxx>
94
95#include <vector>
96
7fd59977 97#ifdef HAVE_TBB
0b97567d
K
98 // paralleling using Intel TBB
99 #include <tbb/parallel_for_each.h>
7fd59977 100#endif
101
51c3cc5f
O
102#define UVDEFLECTION 1.e-05
103
7fd59977 104inline Standard_Real MaxFaceTol (const TopoDS_Face& theFace)
105{
106 Standard_Real T, TMax = BRep_Tool::Tolerance(theFace);
107 TopExp_Explorer Ex;
108
109 for (Ex.Init(theFace,TopAbs_EDGE); Ex.More(); Ex.Next())
110 {
111 T = BRep_Tool::Tolerance(TopoDS::Edge(Ex.Current()));
112 if (T > TMax) TMax = T;
113 }
114
115 for (Ex.Init(theFace,TopAbs_VERTEX); Ex.More(); Ex.Next())
116 {
117 T = BRep_Tool::Tolerance(TopoDS::Vertex(Ex.Current()));
118 if (T > TMax) TMax = T;
119 }
120
121 return TMax;
122}
123
124
125//=======================================================================
126//function : BRepMesh_FastDiscret
127//purpose :
128//=======================================================================
703a6abd
O
129BRepMesh_FastDiscret::BRepMesh_FastDiscret(const Standard_Real theDefle,
130 const Standard_Real theAngl,
131 const Bnd_Box& theBox,
132 const Standard_Boolean theWithShare,
133 const Standard_Boolean theInshape,
134 const Standard_Boolean theRelative,
135 const Standard_Boolean theShapetrigu) :
0b97567d
K
136 myAngle (theAngl),
137 myDeflection (theDefle),
138 myWithShare (theWithShare),
139 myInParallel (Standard_False),
140 myNbLocat (0),
141 myRelative (theRelative),
142 myShapetrigu (theShapetrigu),
143 myInshape (theInshape)
7fd59977 144{
145 myAllocator = new NCollection_IncAllocator(64000);
2b59653e
E
146 if(myRelative)
147 BoxMaxDimension(theBox, myDtotale);
7fd59977 148}
149
150//=======================================================================
151//function : BRepMesh_FastDiscret
152//purpose :
153//=======================================================================
154
703a6abd
O
155BRepMesh_FastDiscret::BRepMesh_FastDiscret(const Standard_Real theDefle,
156 const TopoDS_Shape& theShape,
157 const Bnd_Box& theBox,
158 const Standard_Real theAngl,
159 const Standard_Boolean theWithShare,
160 const Standard_Boolean theInshape,
161 const Standard_Boolean theRelative,
162 const Standard_Boolean theShapetrigu):
0b97567d
K
163 myAngle (theAngl),
164 myDeflection (theDefle),
165 myWithShare (theWithShare),
166 myInParallel (Standard_False),
167 myNbLocat (0),
168 myRelative (theRelative),
169 myShapetrigu (theShapetrigu),
170 myInshape (theInshape)
7fd59977 171{
172 myAllocator = new NCollection_IncAllocator(64000);
2b59653e
E
173 if(myRelative)
174 BoxMaxDimension(theBox, myDtotale);
703a6abd 175 Perform(theShape);
7fd59977 176}
177
2b59653e 178//=======================================================================
0981302b
K
179//function : SetParallel
180//purpose :
181//=======================================================================
182void BRepMesh_FastDiscret::SetParallel (const Standard_Boolean theInParallel)
183{
184 myInParallel = theInParallel;
185}
186
187//=======================================================================
188//function : IsParallel
189//purpose :
190//=======================================================================
191Standard_Boolean BRepMesh_FastDiscret::IsParallel() const
192{
193 return myInParallel;
194}
195
196//=======================================================================
197//function : BoxMaxDimension
198//purpose :
199//=======================================================================
200
201void BRepMesh_FastDiscret::BoxMaxDimension(const Bnd_Box& theBox, Standard_Real& theMaxDim)
202{
203 if(theBox.IsVoid())
204 return;
205 Standard_Real TXmin, TYmin, TZmin, TXmax, TYmax, TZmax;
206 theBox.Get(TXmin, TYmin, TZmin, TXmax, TYmax, TZmax);
207 theMaxDim = TXmax-TXmin;
208 const Standard_Real dy = TYmax-TYmin;
209 const Standard_Real dz = TZmax-TZmin;
210 if (dy > theMaxDim) theMaxDim = dy;
211 if (dz > theMaxDim) theMaxDim = dz;
212}
213
214//=======================================================================
215//function : RelativeEdgeDeflection
216//purpose :
217//=======================================================================
218
219Standard_Real BRepMesh_FastDiscret::RelativeEdgeDeflection(const TopoDS_Edge& theEdge,
220 const Standard_Real theDefle,
221 const Standard_Real theDTotale,
222 Standard_Real& theDefCoef)
223{
224 theDefCoef = 1.;
225 Standard_Real defedge = theDefle;
226 if(theEdge.IsNull())
227 return defedge;
228
229 Bnd_Box B;
230 BRepBndLib::Add(theEdge, B);
231 BoxMaxDimension(B, defedge);
232
233 // adjusted in relation to the total size:
234 theDefCoef = theDTotale/(2*defedge);
235 if (theDefCoef < 0.5) theDefCoef = 0.5;
236 if (theDefCoef > 2.) theDefCoef = 2.;
237 defedge = theDefCoef * defedge * theDefle;
238
239 return defedge;
240}
241
242//=======================================================================
7fd59977 243//function : Perform(shape)
244//purpose :
245//=======================================================================
246
703a6abd 247void BRepMesh_FastDiscret::Perform(const TopoDS_Shape& theShape)
7fd59977 248{
0d36f7e4
O
249 TopTools_IndexedDataMapOfShapeListOfShape anAncestors;
250 TopExp::MapShapesAndAncestors(theShape, TopAbs_EDGE, TopAbs_FACE, anAncestors);
7fd59977 251 std::vector<TopoDS_Face> aFaces;
703a6abd 252 for (TopExp_Explorer ex(theShape, TopAbs_FACE); ex.More(); ex.Next()) {
7fd59977 253 TopoDS_Face aF = TopoDS::Face(ex.Current());
0d36f7e4 254 Add(aF, anAncestors);
7fd59977 255 aFaces.push_back(aF);
256 }
0b97567d
K
257
258 if (myInParallel)
259 {
260 #ifdef HAVE_TBB
261 // mesh faces in parallel threads using TBB
7fd59977 262 tbb::parallel_for_each (aFaces.begin(), aFaces.end(), *this);
0b97567d
K
263 #else
264 // alternative parallelization not yet available
265 for (std::vector<TopoDS_Face>::iterator it(aFaces.begin()); it != aFaces.end(); it++)
266 Process (*it);
267 #endif
268 }
7fd59977 269 else
0b97567d
K
270 {
271 for (std::vector<TopoDS_Face>::iterator it(aFaces.begin()); it != aFaces.end(); it++)
272 Process (*it);
273 }
7fd59977 274}
275
276
277//=======================================================================
278//function : Process
279//purpose :
280//=======================================================================
281
282void BRepMesh_FastDiscret::Process(const TopoDS_Face& theFace) const
283{
284 //cout << "START face " << theFace.TShape().operator->() << endl << flush;
285 Handle(BRepMesh_FaceAttribute) fattribute;
286 if ( GetFaceAttribute (theFace, fattribute) )
287 {
703a6abd 288 BRepMesh_FastDiscretFace aTool (GetAngle(), WithShare());
7fd59977 289 aTool.Add (theFace, fattribute, GetMapOfDefEdge());
290 }
291 //cout << "END face " << theFace.TShape().operator->() << endl << flush;
292}
293
294//=======================================================================
295//function : Add(face)
296//purpose :
297//=======================================================================
298
299#define MESH_FAILURE(theface) \
300{ \
703a6abd
O
301 myFacestate = BRepMesh_Failure; \
302 myNottriangulated.Append(theface); \
7fd59977 303 return; \
304}
305
0d36f7e4
O
306void BRepMesh_FastDiscret::Add(const TopoDS_Face& theface,
307 const TopTools_IndexedDataMapOfShapeListOfShape& theAncestors)
7fd59977 308{
309#ifndef DEB_MESH
310 try
311 {
312 OCC_CATCH_SIGNALS
313#endif
314 TopoDS_Face face = theface;
315 BRepTools::Update(face);
316 face.Orientation(TopAbs_FORWARD);
703a6abd 317 myStructure.Nullify();
7fd59977 318 Handle(NCollection_IncAllocator) anAlloc = Handle(NCollection_IncAllocator)::DownCast(myAllocator);
319 anAlloc->Reset(Standard_False);
703a6abd 320 myStructure=new BRepMesh_DataStructureOfDelaun(anAlloc);
0981302b
K
321
322 Standard_Real aUmin, aVmin, aUmax, aVmax;
323 BRepTools::UVBounds (theface, aUmin, aUmax, aVmin, aVmax);
324 Standard_Real aTolU = (aUmax - aUmin) * UVDEFLECTION;
325 Standard_Real aTolV = (aVmax - aVmin) * UVDEFLECTION;
326 myStructure->Data().SetCellSize ( 14 * aTolU, 14 * aTolV );
327 myStructure->Data().SetTolerance( aTolU, aTolV );
328
7fd59977 329 BRepAdaptor_Surface BS(face, Standard_False);
330 Handle(BRepAdaptor_HSurface) gFace = new BRepAdaptor_HSurface(BS);
331
332 GeomAbs_SurfaceType thetype;
333 thetype = BS.GetType();
334
335 gp_Pnt2d uvFirst, uvLast;
336
7fd59977 337 Handle(Poly_Triangulation) T;
338 TopLoc_Location loc;
339
340 if (!myWithShare) {
703a6abd
O
341 myVertices.Clear();
342 myEdges.Clear();
7fd59977 343 }
344
703a6abd
O
345 myVemap.Clear();
346 myLocation2d.Clear();
347 myInternaledges.Clear();
7fd59977 348
349 Standard_Integer i;
350 i = 1;
351
352 Standard_Real defedge, defface;
7fd59977 353 Standard_Integer nbEdge = 0;
703a6abd 354 Standard_Real savangle = myAngle;
7fd59977 355 Standard_Real cdef;
356 Standard_Real maxdef = 2.* MaxFaceTol(theface);
357 defface = 0.;
358
703a6abd 359 if (!myRelative) defface = Max(myDeflection, maxdef);
7fd59977 360
361 TColStd_SequenceOfReal aFSeq, aLSeq;
362 TColGeom2d_SequenceOfCurve aCSeq;
363 TopTools_SequenceOfShape aShSeq;
364
365 TopoDS_Iterator exW(face);
366
367 for (; exW.More(); exW.Next()) {
368 const TopoDS_Shape& aWire = exW.Value();
369 if (aWire.ShapeType() != TopAbs_WIRE)
370 continue;
371 TopoDS_Iterator ex(aWire);
372 for(; ex.More(); ex.Next()) {
373 const TopoDS_Edge& edge = TopoDS::Edge(ex.Value());
374 nbEdge++;
703a6abd
O
375 if (!myMapdefle.IsBound(edge)) {
376 if (myRelative) {
377 if (myEdges.IsBound(edge)) {
378 const BRepMesh_PairOfPolygon& pair = myEdges.Find(edge);
379 const Handle(Poly_PolygonOnTriangulation)& P = pair.First();
380 defedge = P->Deflection();
381 }
7fd59977 382 else {
2b59653e 383 defedge = RelativeEdgeDeflection(edge, myDeflection, myDtotale, cdef);
703a6abd 384 myAngle = savangle * cdef;
7fd59977 385 }
386 defface = defface + defedge;
703a6abd 387 defface = Max(maxdef, defface);
7fd59977 388 }
703a6abd 389 else defedge = myDeflection;
7fd59977 390
391 defedge = Max(maxdef, defedge);
51c3cc5f 392 defedge = Max(UVDEFLECTION , defedge);
703a6abd 393 myMapdefle.Bind(edge, defedge);
7fd59977 394 }
395 else{
703a6abd
O
396 defedge = myMapdefle(edge);
397 if (myRelative) {defface = defface + defedge; defface = Max(maxdef, defface);}
7fd59977 398 }
399 Standard_Real f1,l1;
400 Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(edge, face, f1, l1);
401 if (C.IsNull()) continue;
402
403 aFSeq.Append(f1);
404 aLSeq.Append(l1);
405 aCSeq.Append(C);
406 aShSeq.Append(edge);
0d36f7e4 407 Add(edge, face, gFace, C, theAncestors, defedge, f1, l1);
703a6abd 408 myAngle = savangle;
7fd59977 409 }
410 }
411
703a6abd 412 if (nbEdge == 0 || myVemap.Extent() < 3)
7fd59977 413 {
414 MESH_FAILURE(theface);
415 }
416
703a6abd
O
417 if (myRelative ) defface = defface / nbEdge;
418 else defface = myDeflection;
7fd59977 419
420 if (myWithShare) defface = Max(maxdef, defface);
421
422 T = BRep_Tool::Triangulation(face, loc);
423
703a6abd 424 if (!myShapetrigu || T.IsNull()) {
7fd59977 425
426 Standard_Real xCur, yCur;
427 Standard_Real maxX, minX, maxY, minY;
428 minX=minY=1.e100;
429 maxX=maxY=-1.e100;
430
431 Standard_Integer ipn = 0;
432 Standard_Integer i1 =1;
703a6abd
O
433 for (i1 = 1; i1 <= myVemap.Extent(); i1++) {
434 const BRepMesh_Vertex& aV = myStructure->GetNode(myVemap.FindKey(i1));
7fd59977 435 ipn++;
436 xCur=aV.Coord().X();
437 yCur=aV.Coord().Y();
438 minX=Min(xCur, minX);
439 maxX=Max(xCur, maxX);
440 minY=Min(yCur, minY);
441 maxY=Max(yCur, maxY);
442 }
443 Standard_Real myumin = minX;
444 Standard_Real myumax = maxX;
445 Standard_Real myvmin = minY;
446 Standard_Real myvmax = maxY;
447
448 const Standard_Real umin = BS.FirstUParameter();
449 const Standard_Real umax = BS.LastUParameter();
450 const Standard_Real vmin = BS.FirstVParameter();
451 const Standard_Real vmax = BS.LastVParameter();
452
453 if (myumin < umin || myumax > umax)
454 {
455 if (BS.IsUPeriodic())
456 {
457 if ((myumax - myumin) > (umax - umin))
458 {
459 myumax = myumin + (umax - umin);
460 }
461 }
462 else
463 {
464 if (umin > myumin) myumin = umin;
465 if (umax < myumax) myumax = umax;
466 }
467 }
468
469 if (myvmin < vmin || myvmax > vmax)
470 {
471 if (BS.IsVPeriodic())
472 {
473 if ((myvmax - myvmin) > (vmax - vmin))
474 {
475 myvmax = myvmin + (vmax - vmin);
476 }
477 }
478 else
479 {
480 if (vmin > myvmin) myvmin = vmin;
481 if (vmax < myvmax) myvmax = vmax;
482 }
483 }
484
485 // fast verification of the validity of calculated limits. If wrong,
486 // sure a problem of pcurve.
487 if (thetype == GeomAbs_BezierSurface &&
488 (myumin < -0.5 || myumax > 1.5 || myvmin < -0.5 || myvmax > 1.5))
489 {
490 MESH_FAILURE(theface);
491 }
492
493 //define parameters for correct parametrics
494
495 Standard_Real deltaX = 1.0;
496 Standard_Real deltaY = 1.0;
703a6abd 497 Standard_Integer nbVertices = myVemap.Extent();
7fd59977 498 const Standard_Real tolclass = Precision::PConfusion(); //0.03*Max(myumax-myumin, myvmax-myvmin);
499
500 BRepMesh_ClassifierPtr classifier (
703a6abd
O
501 new BRepMesh_Classifier(face, tolclass, myInternaledges, myVemap,
502 myStructure, myumin, myumax, myvmin, myvmax) );
7fd59977 503
703a6abd
O
504 myFacestate = classifier->State();
505 if (myFacestate == BRepMesh_SelfIntersectingWire)
7fd59977 506 {
507 Standard_Integer nbmaill = 0;
508 Standard_Real eps = Precision::Confusion();
703a6abd 509 while (nbmaill < 5 && myFacestate != BRepMesh_ReMesh)
7fd59977 510 {
511 nbmaill++;
512
513 //clear the structure of links
703a6abd
O
514 myStructure.Nullify();
515 myStructure = new BRepMesh_DataStructureOfDelaun(anAlloc);
7fd59977 516
703a6abd
O
517 myVemap.Clear();
518 myLocation2d.Clear();
519 myInternaledges.Clear();
7fd59977 520
521 Standard_Integer j1;
522 for(j1 = 1; j1 <= aShSeq.Length(); j1++)
523 {
524 const TopoDS_Edge& edge = TopoDS::Edge(aShSeq.Value(j1));
703a6abd 525 if (myEdges.IsBound(edge))
7fd59977 526 {
703a6abd
O
527 myEdges.UnBind(edge);
528 myInternaledges.UnBind(edge);
7fd59977 529 }
530 }
531
532
533 for( j1 = 1; j1 <= aShSeq.Length(); j1++)
534 {
535 const TopoDS_Edge& edge = TopoDS::Edge(aShSeq.Value(j1));
703a6abd 536 defedge = myMapdefle(edge) / 3.;
7fd59977 537 defedge = Max(defedge, eps);
703a6abd 538 myMapdefle.Bind(edge, defedge);
7fd59977 539 const Handle(Geom2d_Curve)& C = aCSeq.Value(j1);
0d36f7e4 540 Add(edge, face, gFace, C, theAncestors, defedge, aFSeq.Value(j1), aLSeq.Value(j1));
7fd59977 541 }
703a6abd 542
7fd59977 543 classifier.Nullify();
544
703a6abd
O
545 classifier = new BRepMesh_Classifier(face, tolclass, myInternaledges, myVemap,
546 myStructure, myumin, myumax, myvmin, myvmax);
7fd59977 547
548 if (classifier->State() == BRepMesh_NoError)
549 {
703a6abd
O
550 myFacestate = BRepMesh_ReMesh;
551 }
552 nbVertices = myVemap.Extent();
7fd59977 553 }
554 }
555
703a6abd 556 if (myFacestate != BRepMesh_NoError && myFacestate != BRepMesh_ReMesh)
7fd59977 557 {
703a6abd 558 myNottriangulated.Append(face);
7fd59977 559 classifier.Nullify();
560 return;
561 }
562
7fd59977 563 // try to find the real length:
564 // akm (bug OCC16) : We must calculate these measures in non-singular
565 // parts of face. Let's try to compute average value of three
566 // (umin, (umin+umax)/2, umax), and respectively for v.
567 // vvvvv
568 Standard_Real longu = 0.0, longv = 0.0; //, last , first;
569 gp_Pnt P11, P12, P21, P22, P31, P32;
570
571 Standard_Real du = (myumax-myumin)/20;
572 Standard_Real dv = (myvmax-myvmin)/20;
573 Standard_Real dfuave=(myumin+myumax)/2, dfucur;
574 Standard_Real dfvave=(myvmin+myvmax)/2, dfvcur;
575 // U loop
576 BS.D0 (myumin, myvmin, P11);
577 BS.D0 (myumin, dfvave, P21);
578 BS.D0 (myumin, myvmax, P31);
2b59653e 579 for (i1=1, dfucur=myumin+du; i1 <= 20; i1++, dfucur+=du) {
7fd59977 580 BS.D0 (dfucur, myvmin, P12);
581 BS.D0 (dfucur, dfvave, P22);
582 BS.D0 (dfucur, myvmax, P32);
583 longu += ( P11.Distance(P12) + P21.Distance(P22) + P31.Distance(P32) );
584 P11 = P12;
585 P21 = P22;
586 P31 = P32;
587 }
588 // V loop
589 BS.D0(myumin, myvmin, P11);
590 BS.D0(dfuave, myvmin, P21);
591 BS.D0(myumax, myvmin, P31);
2b59653e 592 for (i1=1, dfvcur=myvmin+dv; i1 <= 20; i1++, dfvcur+=dv) {
7fd59977 593 BS.D0 (myumin, dfvcur, P12);
594 BS.D0 (dfuave, dfvcur, P22);
595 BS.D0 (myumax, dfvcur, P32);
596 longv += ( P11.Distance(P12) + P21.Distance(P22) + P31.Distance(P32) );
597 P11 = P12;
598 P21 = P22;
599 P31 = P32;
600 }
601 longu /= 3.;
602 longv /= 3.;
603 // akm (bug OCC16) ^^^^^
604
605 if (longu <= 1.e-16 || longv <= 1.e-16) {
703a6abd 606 //yes, it is seen!!
7fd59977 607#ifdef DEB_MESH_CHRONO
608 chMaillEdges.Stop();
609 MESH_CHRONO_TSTOP(thetype);
610#endif
611 MESH_FAILURE(theface);
612 }
613
614
615 if (thetype == GeomAbs_Torus) {
616 gp_Torus Tor = BS.Torus();
617 Standard_Real r = Tor.MinorRadius(), R = Tor.MajorRadius();
618 Standard_Real Du, Dv;//, pasu, pasv;
619
620 Dv = Max(1.0e0 - (defface/r),0.0e0) ;
621 Standard_Real oldDv = 2.0 * ACos (Dv);
703a6abd 622 oldDv = Min(oldDv, myAngle);
7fd59977 623 Dv = 0.9*oldDv; //TWOTHIRD * oldDv;
624 Dv = oldDv;
625
626 Standard_Integer nbV = Max((Standard_Integer)((myvmax-myvmin)/Dv), 2);
627 Dv = (myvmax-myvmin)/(nbV+1);
628
629 Standard_Real ru = R + r;
630 if (ru > 1.e-16) {
631 Du = Max(1.0e0 - (defface/ru),0.0e0);
632 Du = (2.0 * ACos (Du));
703a6abd 633 Du = Min(Du, myAngle);
7fd59977 634 Standard_Real aa = sqrt(Du*Du + oldDv*oldDv);
635 if(aa < gp::Resolution())
636 return;
637
638 Du = Du * Min(oldDv, Du) / aa;
639 }
640 else Du = Dv;
703a6abd 641
7fd59977 642 Standard_Integer nbU = Max((Standard_Integer)((myumax-myumin)/Du), 2);
643 nbU = Max(nbU, (Standard_Integer)(nbV*(myumax-myumin)*R/((myvmax-myvmin)*r)/5.));
644
645 Du = (myumax-myumin)/(nbU+1);
646 //-- DeltaX and DeltaY are chosen so that to avoid "jumping"
647 //-- of points on the grid
648 deltaX = Du;
649 deltaY = Dv;
650 }
651 else if (thetype == GeomAbs_Cylinder) {
652 /*Standard_Real aMax = Max(myumax,myvmax);
653 deltaX = 0.01; //1./aMax; //0.01;
654 deltaY = 1.0;*/
655 gp_Cylinder Cyl = BS.Cylinder();
656 Standard_Real R = Cyl.Radius();
657 // Calculate parameters for iteration in U direction
658 Standard_Real Du = 1.0 - (defface/R);
659 if (Du < 0.0) Du = 0.0;
660 Du = 2.0 * ACos (Du);
661 if (Du > GetAngle()) Du = GetAngle();
662 deltaX = Du/longv;
663 deltaY = 1.;
664 }
665 else {
666 deltaX = (myumax-myumin)/longu;
667 deltaY = (myvmax-myvmin)/longv;
668 }
669
703a6abd 670 if(!myMapattrib.IsBound(theface))
7fd59977 671 {
672 Handle(BRepMesh_FaceAttribute) aFA = new BRepMesh_FaceAttribute();
673 aFA->GetDefFace() = defface;
674 aFA->GetUMax() = myumax;
675 aFA->GetVMax() = myvmax;
676 aFA->GetUMin() = myumin;
677 aFA->GetVMin() = myvmin;
678 aFA->GetDeltaX() = deltaX;
679 aFA->GetDeltaY() = deltaY;
680 aFA->GetMinX() = minX;
681 aFA->GetMinY() = minY;
682 aFA->GetClassifier() = classifier;
703a6abd 683 myMapattrib.Bind(theface, aFA);
7fd59977 684 }
685
703a6abd 686 //Standard_Integer nbVertices = myVemap.Extent();
7fd59977 687 T = new Poly_Triangulation(nbVertices, 1, Standard_True);
688 TColgp_Array1OfPnt& Nodes = T->ChangeNodes();
689 TColgp_Array1OfPnt2d& Nodes2d = T->ChangeUVNodes();
690
691 Standard_Integer index;
692 for (i = 1; i <= nbVertices; i++) {
703a6abd 693 index = myVemap.FindKey(i);
7fd59977 694 Nodes(i) = Pnt(index);
695 Nodes2d(i).SetXY(Vertex(index).Coord());
696 }
697
698 // storage of triangulation in the BRep.
699 //TopLoc_Location loc = face.Location();
700 if (!loc.IsIdentity()) {
701 gp_Trsf tr = loc.Transformation();
702 tr.Invert();
703 for (i = Nodes.Lower(); i <= Nodes.Upper(); i++)
703a6abd 704 Nodes(i).Transform(tr);
7fd59977 705 }
706
707 BRep_Builder B;
708 B.UpdateFace(face, T);
709
703a6abd 710 BRepMesh_DataMapIteratorOfDataMapOfShapePairOfPolygon It(myInternaledges);
7fd59977 711 for (; It.More(); It.Next()) {
712 const BRepMesh_PairOfPolygon& pair = It.Value();
713 const Handle(Poly_PolygonOnTriangulation)& NOD1 = pair.First();
714 const Handle(Poly_PolygonOnTriangulation)& NOD2 = pair.Last();
715 if ( NOD1 == NOD2 )
703a6abd 716 B.UpdateEdge(TopoDS::Edge(It.Key()), NOD1, T, loc);
7fd59977 717 else
703a6abd 718 B.UpdateEdge(TopoDS::Edge(It.Key()), NOD1, NOD2, T, loc);
7fd59977 719 }
720 }
721
722#ifndef DEB_MESH
723 }
724 catch(Standard_Failure)
725 {
726 MESH_FAILURE(theface);
727 }
728#endif // DEB_MESH
703a6abd 729 myStructure.Nullify();
7fd59977 730}
731
0d36f7e4
O
732//=======================================================================
733//function : splitSegment
734//purpose :
735//=======================================================================
736static void splitSegment( BRepMesh_GeomTool& theGT,
737 const Handle(Geom_Surface)& theSurf,
738 const Handle(Geom2d_Curve)& theCurve2d,
739 const BRepAdaptor_Curve& theBAC,
740 const Standard_Real theSquareEDef,
741 const Standard_Real theFirst,
742 const Standard_Real theLast,
743 const Standard_Integer theNbIter)
744{
745 //limit ineration depth
746 if(theNbIter > 10)
747 return;
748 gp_Pnt2d uvf, uvl, uvm;
749 gp_Pnt P3dF, P3dL, midP3d, midP3dFromSurf;
750 Standard_Real midpar;
751
752 if(Abs(theLast - theFirst) < 2*Precision::PConfusion())
753 return;
754
755 theCurve2d->D0(theFirst, uvf);
756 theCurve2d->D0(theLast, uvl);
757
758 P3dF = theSurf->Value(uvf.X(), uvf.Y());
759 P3dL = theSurf->Value(uvl.X(), uvl.Y());
760
761 if(P3dF.SquareDistance(P3dL) < theSquareEDef)
762 return;
763
764 uvm = gp_Pnt2d((uvf.XY() + uvl.XY())*0.5);
765 midP3dFromSurf = theSurf->Value(uvm.X(), uvm.Y());
766
767 gp_XYZ aVec = P3dL.XYZ()-P3dF.XYZ();
768 aVec.Normalize();
769
770 gp_XYZ Vec1 = midP3dFromSurf.XYZ() - P3dF.XYZ();
771 Standard_Real aModulus = Vec1.Dot(aVec);
772 gp_XYZ aProj = aVec*aModulus;
773 gp_XYZ aDist = Vec1 - aProj;
774
775 if(aDist.SquareModulus() < theSquareEDef)
776 return;
777
778 midpar = (theFirst + theLast) * 0.5;
779 theBAC.D0(midpar, midP3d);
780 theGT.AddPoint(midP3d, midpar, Standard_False);
781
782 splitSegment(theGT, theSurf, theCurve2d, theBAC, theSquareEDef, theFirst, midpar, theNbIter+1);
783 splitSegment(theGT, theSurf, theCurve2d, theBAC, theSquareEDef, midpar, theLast, theNbIter+1);
784}
785
7fd59977 786//=======================================================================
787//function : Add
788//purpose :
789//=======================================================================
703a6abd
O
790void BRepMesh_FastDiscret::Add( const TopoDS_Edge& theEdge,
791 const TopoDS_Face& theFace,
792 const Handle(BRepAdaptor_HSurface)& theGFace,
793 const Handle(Geom2d_Curve)& theC2d,
0d36f7e4 794 const TopTools_IndexedDataMapOfShapeListOfShape& theAncestors,
703a6abd
O
795 const Standard_Real theDefEdge,
796 const Standard_Real theFirst,
797 const Standard_Real theLast)
7fd59977 798{
703a6abd 799 const TopAbs_Orientation orEdge = theEdge.Orientation();
7fd59977 800 if (orEdge == TopAbs_EXTERNAL) return;
801
703a6abd 802 const Standard_Boolean isEdgeBound = myEdges.IsBound(theEdge);
7fd59977 803
804 if (!isEdgeBound)
805 {
703a6abd 806 if (Update(theEdge, theFace, theC2d, theDefEdge, theFirst, theLast))
7fd59977 807 {
808 return;
809 }
810 }
811
812 TopoDS_Vertex pBegin, pEnd;
703a6abd 813 TopExp::Vertices(theEdge, pBegin, pEnd);
7fd59977 814 if (pBegin.IsNull() || pEnd.IsNull())
815 {
816 return;
817 }
818
819 Standard_Real wFirst, wLast;
703a6abd 820 BRep_Tool::Range(theEdge, theFace, wFirst, wLast);
7fd59977 821
822 gp_Pnt2d uvFirst, uvLast;
703a6abd 823 BRep_Tool::UVPoints(theEdge, theFace, uvFirst, uvLast);
7fd59977 824
825 const Standard_Boolean sameUV = uvFirst.IsEqual(uvLast, Precision::PConfusion());
826
827 //Control vertexes tolerances
703a6abd
O
828 gp_Pnt pFirst = theGFace->Value(uvFirst.X(), uvFirst.Y());
829 gp_Pnt pLast = theGFace->Value(uvLast.X(), uvLast.Y());
7fd59977 830
831 Standard_Real mindist = 10. * Max(pFirst.Distance(BRep_Tool::Pnt(pBegin)),
703a6abd 832 pLast.Distance(BRep_Tool::Pnt(pEnd)));
7fd59977 833
834 if(mindist < BRep_Tool::Tolerance(pBegin) ||
703a6abd 835 mindist < BRep_Tool::Tolerance(pEnd) ) mindist = theDefEdge;
7fd59977 836
837 // control of degenerated non-coded edges.
838
703a6abd 839 Standard_Boolean degener = BRep_Tool::Degenerated(theEdge);
7fd59977 840
841 if (!degener)
842 {
843 if (pBegin.IsSame(pEnd))
844 {
845 // calculation of the length of the edge in 3D
846 Standard_Real longueur = 0.0;
847 Standard_Real du = (wLast-wFirst)/20;
848 gp_Pnt P1, P2;
703a6abd 849 BRepAdaptor_Curve BC(theEdge);
7fd59977 850 BC.D0(wFirst, P1);
851 Standard_Real tolV = BRep_Tool::Tolerance(pBegin);
852 Standard_Real tolV2 = 1.2*tolV;
853 for (Standard_Integer l = 1; l <= 20; l++) {
703a6abd
O
854 BC.D0(wFirst + l*du, P2);
855 longueur += P1.Distance(P2);
856 if (longueur > tolV2) break;
857 P1 = P2;
7fd59977 858 }
859
860 if (longueur < tolV2)
861 {
703a6abd 862 degener = Standard_True;
7fd59977 863 }
864 }
865 }
866
867 // Correct UV points
868 if (sameUV)
869 {
870 // 1. is it really sameUV without being degenerated
871 gp_Pnt2d uvF, uvL;
703a6abd
O
872 theC2d->D0(theFirst, uvF);
873 theC2d->D0(theLast, uvL);
7fd59977 874 if (!uvFirst.IsEqual(uvF, Precision::PConfusion()))
875 {
876 uvFirst = uvF;
877 }
878 if (!uvLast.IsEqual(uvL, Precision::PConfusion()))
879 {
880 uvLast = uvL;
881 }
882 }
883
884 gp_XY theUV;
885
886 // Process first vertex
887 Standard_Integer ipf;
703a6abd 888 if (myVertices.IsBound(pBegin))
7fd59977 889 {
703a6abd 890 ipf = myVertices.Find(pBegin);
7fd59977 891 }
892 else
893 {
703a6abd 894 if (sameUV && myVertices.IsBound(pEnd))
7fd59977 895 {
703a6abd 896 ipf = myVertices.Find(pEnd);
7fd59977 897 }
898 else
899 {
703a6abd
O
900 myNbLocat++;
901 ipf = myNbLocat;
902 myLocation3d.Bind(ipf, BRep_Tool::Pnt(pBegin));
7fd59977 903 }
703a6abd 904 myVertices.Bind(pBegin, ipf);
7fd59977 905 }
703a6abd 906 theUV = BRepMesh_FastDiscretFace::FindUV(pBegin, uvFirst, ipf, theGFace, mindist, myLocation2d);
0d88155b 907 BRepMesh_Vertex vf(theUV, ipf, BRepMesh_Frontier);
703a6abd 908 Standard_Integer ivf = myStructure->AddNode(vf);
7fd59977 909
910 // Process last vertex
911 Standard_Integer ipl;
912 if (pEnd.IsSame(pBegin))
913 {
914 ipl = ipf;
915 }
916 else
917 {
703a6abd 918 if (myVertices.IsBound(pEnd))
7fd59977 919 {
703a6abd 920 ipl = myVertices.Find(pEnd);
7fd59977 921 }
922 else
923 {
924 if (sameUV)
925 {
926 ipl = ipf;
927 }
928 else
929 {
703a6abd
O
930 myNbLocat++;
931 ipl = myNbLocat;
932 myLocation3d.Bind(ipl, BRep_Tool::Pnt(pEnd));
7fd59977 933 }
703a6abd 934 myVertices.Bind(pEnd,ipl);
7fd59977 935 }
936 }
703a6abd 937 theUV = BRepMesh_FastDiscretFace::FindUV(pEnd, uvLast, ipl, theGFace, mindist, myLocation2d);
0d88155b 938 BRepMesh_Vertex vl(theUV, ipl, BRepMesh_Frontier);
703a6abd 939 Standard_Integer ivl= myStructure->AddNode(vl);
7fd59977 940
703a6abd
O
941 Standard_Integer isvf = myVemap.FindIndex(ivf);
942 if (isvf == 0) isvf = myVemap.Add(ivf);
943 Standard_Integer isvl = myVemap.FindIndex(ivl);
944 if (isvl == 0) isvl = myVemap.Add(ivl);
7fd59977 945
703a6abd 946 Standard_Real otherdefedge = 0.5*theDefEdge;
7fd59977 947 gp_Pnt2d uv;
948 BRepMesh_Vertex v2;
949 gp_Pnt P3d;
950
951 Handle(Poly_PolygonOnTriangulation) P1;
952
953 if (!isEdgeBound)
954 {
955 Handle(Poly_PolygonOnTriangulation) P2;
956
957 if (degener)
958 {
959 // creation anew:
960 TColStd_Array1OfInteger Nodes(1, 2), NodInStruct(1, 2);
961 TColStd_Array1OfReal Param(1, 2);
962
963 NodInStruct(1) = ipf;
964 Nodes(1) = isvf;
965 Param(1) = wFirst;
966
967 NodInStruct(2) = ipl;
968 Nodes(2) = isvl;
969 Param(2) = wLast;
970
971 P1 = new Poly_PolygonOnTriangulation(Nodes, Param);
972 P2 = new Poly_PolygonOnTriangulation(NodInStruct, Param);
973 }
974 else
975 {
976 if (orEdge == TopAbs_INTERNAL) otherdefedge *= 0.5;
977
978 BRepAdaptor_Curve cons;
0d36f7e4
O
979 Standard_Boolean isSameParam = BRep_Tool::SameParameter(theEdge);
980 if (isSameParam)
7fd59977 981 {
703a6abd 982 cons.Initialize(theEdge);
7fd59977 983 }
984 else
985 {
703a6abd 986 cons.Initialize(theEdge, theFace);
7fd59977 987 }
988
989 TopLoc_Location L;
990 Standard_Integer nbpmin = 2;
991 if (cons.GetType() == GeomAbs_Circle) nbpmin = 4; //OCC287
703a6abd 992 BRepMesh_GeomTool GT(cons, wFirst, wLast, 0.5*myAngle, otherdefedge, nbpmin);
7fd59977 993
994 // PTv, chl/922/G9, Take into account internal vertices
703a6abd
O
995 // it is necessary for internal edges, which do not split other edges, by their vertex
996 TopoDS_Iterator exV(theEdge);
7fd59977 997 for ( ; exV.More(); exV.Next() )
998 {
703a6abd
O
999 TopoDS_Vertex aIntV = TopoDS::Vertex(exV.Value());
1000 if ( aIntV.Orientation() == TopAbs_INTERNAL )
7fd59977 1001 GT.AddPoint(BRep_Tool::Pnt(aIntV),
703a6abd
O
1002 BRep_Tool::Parameter(aIntV, theEdge),
1003 Standard_True);
7fd59977 1004 }
1005
0d36f7e4
O
1006 Standard_Integer i;
1007 Standard_Integer nbnodes = GT.NbPoints();
1008 //Check deflection in 2d space for improvement of edge tesselation.
1009 if( isSameParam && nbnodes > 1)
1010 {
1011 Standard_Real aSquareEdgeDef = otherdefedge * otherdefedge;
1012 const TopTools_ListOfShape& lf = theAncestors.FindFromKey(theEdge);
1013 TopTools_ListIteratorOfListOfShape itl(lf);
1014 for (; itl.More(); itl.Next()) {
1015 const TopoDS_Face& aFace = TopoDS::Face (itl.Value());
1016
1017 TopLoc_Location aLoc;
1018 Standard_Real aF, aL;
1019 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace, aLoc);
1020 const Handle(Standard_Type)& aType = aSurf->DynamicType();
1021 if(aType == STANDARD_TYPE(Geom_Plane))
1022 continue;
1023 Handle(Geom2d_Curve) aCurve2d = BRep_Tool::CurveOnSurface(theEdge, aFace, aF, aL);
1024 if(Abs(aF-wFirst)>Precision::PConfusion()||Abs(aL-wLast)>Precision::PConfusion())
1025 continue;
1026
1027 gp_Pnt2d uvf;
1028 Standard_Real parf;
1029 nbnodes = GT.NbPoints();
1030 TColStd_Array1OfReal aParamArray(1, nbnodes);
1031 for (i = 1; i <= nbnodes; i++)
1032 {
1033 GT.Value(cons, theGFace, i, parf, P3d, uvf);
1034 aParamArray.SetValue(i, parf);
1035 }
1036 for (i = 1; i < nbnodes; i++)
1037 {
1038 splitSegment(GT, aSurf, aCurve2d, cons, aSquareEdgeDef, aParamArray(i), aParamArray(i+1), 1);
1039 }
1040 }
1041 }
1042
ae075275 1043 // Creation of polygons on triangulation:
7fd59977 1044 Standard_Real puv;
0d36f7e4 1045 nbnodes = GT.NbPoints();
7fd59977 1046
7fd59977 1047 TColStd_Array1OfInteger Nodes(1, nbnodes);
1048 TColStd_Array1OfInteger NodInStruct(1, nbnodes);
1049 TColStd_Array1OfReal Param(1, nbnodes);
703a6abd 1050
7fd59977 1051 // processing of the 1st point:
1052 Nodes(1) = isvf;
1053 NodInStruct(1) = ipf;
1054 Param(1) = wFirst;
1055
1056 // last point:
1057 Nodes(nbnodes) = isvl;
1058 NodInStruct(nbnodes) = ipl;
1059 Param(nbnodes) = wLast;
1060
1061 if(nbnodes > 2)
1062 {
1063 Standard_Integer iv2;
1064 for (i = 2; i < GT.NbPoints(); i++)
1065 {
1066 // Record 3d point
703a6abd
O
1067 GT.Value(cons, theGFace, i, puv, P3d, uv);
1068 myNbLocat++;
1069 myLocation3d.Bind(myNbLocat, P3d);
1070 NodInStruct(i) = myNbLocat;
7fd59977 1071 // Record 2d point
0d88155b 1072 v2.Initialize(uv.Coord(), myNbLocat, BRepMesh_OnCurve);
703a6abd 1073 iv2=myStructure->AddNode(v2);
7fd59977 1074
703a6abd
O
1075 Standard_Integer isv = myVemap.FindIndex(iv2);
1076 if (isv == 0) isv = myVemap.Add(iv2);
7fd59977 1077 Nodes(i) = isv;
703a6abd 1078 NodInStruct(i) = myNbLocat;
7fd59977 1079 Param(i) = puv;
703a6abd 1080
7fd59977 1081 if (orEdge == TopAbs_FORWARD)
0d88155b 1082 myStructure->AddLink(BRepMesh_Edge(ivf, iv2, BRepMesh_Frontier));
7fd59977 1083 else if (orEdge == TopAbs_REVERSED)
0d88155b 1084 myStructure->AddLink(BRepMesh_Edge(iv2, ivf, BRepMesh_Frontier));
7fd59977 1085 else if (orEdge == TopAbs_INTERNAL)
0d88155b 1086 myStructure->AddLink(BRepMesh_Edge(ivf, iv2, BRepMesh_Fixed));
7fd59977 1087 ivf = iv2;
1088 }
1089 }
1090
1091 P1 = new Poly_PolygonOnTriangulation(Nodes, Param);
1092 P2 = new Poly_PolygonOnTriangulation(NodInStruct, Param);
1093 }
1094
1095 P2->Deflection(otherdefedge);
1096 BRepMesh_PairOfPolygon pair;
1097 pair.Append(P2);
703a6abd 1098 myEdges.Bind(theEdge, pair);
7fd59977 1099
1100 if (ivf != ivl) {
1101 if (orEdge == TopAbs_FORWARD)
0d88155b 1102 myStructure->AddLink(BRepMesh_Edge(ivf, ivl, BRepMesh_Frontier));
7fd59977 1103 else if (orEdge == TopAbs_REVERSED)
0d88155b 1104 myStructure->AddLink(BRepMesh_Edge(ivl, ivf, BRepMesh_Frontier));
7fd59977 1105 else if (orEdge == TopAbs_INTERNAL)
0d88155b 1106 myStructure->AddLink(BRepMesh_Edge(ivf, ivl, BRepMesh_Fixed));
7fd59977 1107 }
1108
1109
1110 }
1111 // If this Edge has been already checked and it is not degenerated,
1112 // the points of the polygon calculated at the first check are retrieved :
1113 else
1114 {
1115 if (degener)
1116 {
1117 // Create 2d polygon for degenerated edge
1118 TColStd_Array1OfInteger Nodes(1, 2);
1119 TColStd_Array1OfReal PPar(1, 2);
1120
1121 Nodes(1) = isvf;
1122 PPar(1) = wFirst;
1123
1124 Nodes(2) = isvl;
1125 PPar(2) = wLast;
1126
1127 P1 = new Poly_PolygonOnTriangulation(Nodes, PPar);
1128 }
1129 else
1130 {
1131 // retrieve the polygone:
703a6abd 1132 const BRepMesh_PairOfPolygon& pair = myEdges.Find(theEdge);
7fd59977 1133 const Handle(Poly_PolygonOnTriangulation)& P = pair.First();
1134 const TColStd_Array1OfInteger& NOD = P->Nodes();
1135 Handle(TColStd_HArray1OfReal) Par = P->Parameters();
1136
1137 // creation anew:
1138 const Standard_Integer nbnodes = NOD.Length();
1139 TColStd_Array1OfInteger Nodes(1, nbnodes);
1140 TColStd_Array1OfReal PPar(1, nbnodes);
1141 Standard_Integer iv2;
1142
1143 Nodes(1) = isvf;
1144 PPar(1) = wFirst;
1145
1146 Nodes(nbnodes) = isvl;
1147 PPar(nbnodes) = wLast;
1148
1149 if (nbnodes > 2)
1150 {
1151 Standard_Integer i;
703a6abd 1152 if (BRep_Tool::SameParameter(theEdge))
7fd59977 1153 {
703a6abd 1154 for (i = 2; i < nbnodes; i++)
7fd59977 1155 {
1156 const Standard_Real puv = Par->Value(i);
703a6abd 1157 theC2d->D0(puv, uv);
0d88155b 1158 v2.Initialize(uv.Coord(), NOD(i), BRepMesh_OnCurve);
703a6abd
O
1159 iv2 = myStructure->AddNode(v2);
1160
1161 Standard_Integer isv = myVemap.FindIndex(iv2);
1162 if (isv == 0) isv = myVemap.Add(iv2);
7fd59977 1163 Nodes(i) = isv;
703a6abd 1164 PPar(i) = puv;
7fd59977 1165
1166 if (orEdge==TopAbs_FORWARD)
0d88155b 1167 myStructure->AddLink(BRepMesh_Edge(ivf, iv2, BRepMesh_Frontier));
703a6abd 1168 else if (orEdge == TopAbs_REVERSED)
0d88155b 1169 myStructure->AddLink(BRepMesh_Edge(iv2, ivf, BRepMesh_Frontier));
7fd59977 1170 else if (orEdge == TopAbs_INTERNAL)
0d88155b 1171 myStructure->AddLink(BRepMesh_Edge(ivf, iv2, BRepMesh_Fixed));
703a6abd 1172
7fd59977 1173 ivf = iv2;
703a6abd
O
1174 }
1175 }
7fd59977 1176 else
1177 {
703a6abd
O
1178 const Standard_Real wFold = Par->Value(Par->Lower());
1179 const Standard_Real wLold = Par->Value(Par->Upper());
7fd59977 1180
703a6abd
O
1181 Standard_Real wKoef = 1.;
1182 if ((wFold != wFirst || wLold != wLast) && wLold != wFold)
7fd59977 1183 {
703a6abd
O
1184 wKoef = (wLast - wFirst) / (wLold - wFold);
1185 }
1186
1187 BRepAdaptor_Curve cons(theEdge, theFace);
1188 Extrema_LocateExtPC pcos;
1189 pcos.Initialize(cons, cons.FirstParameter(),
1190 cons.LastParameter(), Precision::PConfusion());
1191
1192 Standard_Real wPrev;
1193 Standard_Real wCur = wFirst;
1194 Standard_Real wCurFound = wFirst;
1195 for (i = 2; i < nbnodes; i++)
7fd59977 1196 {
703a6abd 1197 P3d = myLocation3d(NOD(i));
7fd59977 1198 // Record 2d point
703a6abd
O
1199 wPrev = wCur;
1200 wCur = wFirst + wKoef*(Par->Value(i) - wFold);
1201 wCurFound += (wCur - wPrev);
1202 pcos.Perform(P3d, wCurFound);
1203 if (pcos.IsDone()) wCurFound = pcos.Point().Parameter();
1204 theC2d->D0(wCurFound, uv);
0d88155b 1205 v2.Initialize(uv.Coord(), NOD(i), BRepMesh_OnCurve);
703a6abd
O
1206 iv2 = myStructure->AddNode(v2);
1207
1208 Standard_Integer isv = myVemap.FindIndex(iv2);
1209 if (isv == 0) isv = myVemap.Add(iv2);
1210 Nodes(i) = isv;
1211 PPar(i) = wCurFound;
1212
7fd59977 1213 if (orEdge==TopAbs_FORWARD)
0d88155b 1214 myStructure->AddLink(BRepMesh_Edge(ivf, iv2, BRepMesh_Frontier));
7fd59977 1215 else if (orEdge == TopAbs_REVERSED)
0d88155b 1216 myStructure->AddLink(BRepMesh_Edge(iv2, ivf, BRepMesh_Frontier));
7fd59977 1217 else if (orEdge == TopAbs_INTERNAL)
0d88155b 1218 myStructure->AddLink(BRepMesh_Edge(ivf, iv2, BRepMesh_Fixed));
703a6abd 1219
7fd59977 1220 ivf = iv2;
703a6abd
O
1221 }
1222 }
7fd59977 1223 }
1224
703a6abd 1225 P1 = new Poly_PolygonOnTriangulation(Nodes, PPar);
7fd59977 1226
1227 if (ivf != ivl) {
1228 if (orEdge == TopAbs_FORWARD)
0d88155b 1229 myStructure->AddLink(BRepMesh_Edge(ivf, ivl, BRepMesh_Frontier));
7fd59977 1230 else if (orEdge == TopAbs_REVERSED)
0d88155b 1231 myStructure->AddLink(BRepMesh_Edge(ivl, ivf, BRepMesh_Frontier));
7fd59977 1232 else if (orEdge == TopAbs_INTERNAL)
0d88155b 1233 myStructure->AddLink(BRepMesh_Edge(ivf, ivl, BRepMesh_Fixed));
7fd59977 1234 }
1235 }
1236 }
1237
703a6abd
O
1238 P1->Deflection(theDefEdge);
1239 if (myInternaledges.IsBound(theEdge))
7fd59977 1240 {
703a6abd 1241 BRepMesh_PairOfPolygon& pair = myInternaledges.ChangeFind(theEdge);
7fd59977 1242 if (orEdge == TopAbs_REVERSED)
1243 pair.Append(P1);
1244 else
1245 pair.Prepend(P1);
1246 }
1247 else
1248 {
1249 BRepMesh_PairOfPolygon pair1;
1250 pair1.Append(P1);
703a6abd 1251 myInternaledges.Bind(theEdge, pair1);
7fd59977 1252 }
1253}
1254
1255
1256//=======================================================================
1257//function : Update(edge)
1258//purpose :
1259//=======================================================================
703a6abd
O
1260Standard_Boolean BRepMesh_FastDiscret::Update(const TopoDS_Edge& theEdge,
1261 const TopoDS_Face& theFace,
1262 const Handle(Geom2d_Curve)& theC2d,
1263 const Standard_Real theDefEdge,
1264 const Standard_Real theFirst,
1265 const Standard_Real theLast)
7fd59977 1266{
703a6abd 1267 TopLoc_Location Loc;
7fd59977 1268 Handle(Poly_Triangulation) T, TNull;
1269 Handle(Poly_PolygonOnTriangulation) Poly, NullPoly;
1270
1271 Standard_Integer i = 1;
1272 Standard_Boolean found = Standard_False;
1273 do
1274 {
703a6abd 1275 BRep_Tool::PolygonOnTriangulation(theEdge,Poly,T,Loc,i);
7fd59977 1276 i++;
1277 if (!found && !T.IsNull() && T->HasUVNodes() &&
703a6abd 1278 !Poly.IsNull() && Poly->HasParameters())
7fd59977 1279 {
703a6abd 1280 if (Poly->Deflection() <= 1.1*theDefEdge)
7fd59977 1281 {
1282 // 2d vertex indices
703a6abd 1283 TopAbs_Orientation orEdge = theEdge.Orientation();
7fd59977 1284 Standard_Integer iv1, iv2, ivl;
1285 Standard_Integer isv1, isv, isvl;
1286
1287 // Get range on 2d curve
703a6abd
O
1288 Standard_Real wFirst, wLast;
1289 BRep_Tool::Range(theEdge, theFace, wFirst, wLast);
1290
7fd59977 1291 // Get end points on 2d curve
703a6abd
O
1292 gp_Pnt2d uvFirst, uvLast;
1293 BRep_Tool::UVPoints(theEdge, theFace, uvFirst, uvLast);
7fd59977 1294
1295 // Get vertices
703a6abd
O
1296 TopoDS_Vertex pBegin, pEnd;
1297 TopExp::Vertices(theEdge,pBegin,pEnd);
1298
1299 const Standard_Boolean sameUV =
7fd59977 1300 uvFirst.IsEqual(uvLast, Precision::PConfusion());
703a6abd
O
1301
1302 //Controle vertice tolerances
1303 BRepAdaptor_Surface BS(theFace, Standard_False);
7fd59977 1304 Handle(BRepAdaptor_HSurface) gFace = new BRepAdaptor_HSurface(BS);
703a6abd 1305
7fd59977 1306
703a6abd
O
1307 gp_Pnt pFirst = gFace->Value(uvFirst.X(), uvFirst.Y());
1308 gp_Pnt pLast = gFace->Value(uvLast.X(), uvLast.Y());
1309
1310 Standard_Real mindist = 10. * Max(pFirst.Distance(BRep_Tool::Pnt(pBegin)),
1311 pLast.Distance(BRep_Tool::Pnt(pEnd)));
7fd59977 1312
703a6abd
O
1313 if (mindist < BRep_Tool::Tolerance(pBegin) ||
1314 mindist < BRep_Tool::Tolerance(pEnd) ) mindist = theDefEdge;
1315
1316 if (sameUV)
7fd59977 1317 {
703a6abd
O
1318 // 1. is it really sameUV without being degenerated
1319 gp_Pnt2d uvF, uvL;
1320 theC2d->D0(theFirst, uvF);
1321 theC2d->D0(theLast, uvL);
1322 if (!uvFirst.IsEqual(uvF, Precision::PConfusion())) {
1323 uvFirst = uvF;
1324 }
1325 if (!uvLast.IsEqual(uvL, Precision::PConfusion())) {
1326 uvLast = uvL;
1327 }
1328 }
7fd59977 1329
703a6abd
O
1330 const TColgp_Array1OfPnt& Nodes = T->Nodes();
1331 const TColStd_Array1OfInteger& Indices = Poly->Nodes();
1332 Handle(TColStd_HArray1OfReal) Param = Poly->Parameters();
1333
1334 const Standard_Integer nbnodes = Indices.Length();
1335 TColStd_Array1OfInteger NewNodes(1, nbnodes);
1336 TColStd_Array1OfInteger NewNodInStruct(1, nbnodes);
1337
7fd59977 1338 gp_Pnt P3d;
703a6abd
O
1339 gp_XY theUV;
1340
7fd59977 1341 // Process first vertex
1342 Standard_Integer ipf;
703a6abd 1343 if (myVertices.IsBound(pBegin))
7fd59977 1344 {
703a6abd
O
1345 ipf = myVertices.Find(pBegin);
1346 }
7fd59977 1347 else
1348 {
703a6abd 1349 if (sameUV && myVertices.IsBound(pEnd))
7fd59977 1350 {
703a6abd
O
1351 ipf = myVertices.Find(pEnd);
1352 }
1353 else
7fd59977 1354 {
703a6abd
O
1355 P3d = Nodes(Indices(1));
1356 if (!Loc.IsIdentity())
1357 P3d.Transform(Loc.Transformation());
1358 myNbLocat++;
1359 myLocation3d.Bind(myNbLocat,P3d);
1360 ipf = myNbLocat;
1361 }
1362 myVertices.Bind(pBegin,ipf);
1363 }
1364 NewNodInStruct(1) = ipf;
1365 theUV = BRepMesh_FastDiscretFace::FindUV(pBegin, uvFirst, ipf, gFace, mindist, myLocation2d);
0d88155b 1366 BRepMesh_Vertex vf(theUV,ipf,BRepMesh_Frontier);
703a6abd
O
1367 iv1 = myStructure->AddNode(vf);
1368 isv1 = myVemap.FindIndex(iv1);
1369 if (isv1 == 0) isv1 = myVemap.Add(iv1);
1370 NewNodes(1) = isv1;
1371
7fd59977 1372 // Process last vertex
1373 Standard_Integer ipl;
1374 if (pEnd.IsSame(pBegin))
1375 {
1376 ipl = ipf;
1377 }
1378 else
1379 {
703a6abd 1380 if (myVertices.IsBound(pEnd))
7fd59977 1381 {
703a6abd 1382 ipl = myVertices.Find(pEnd);
7fd59977 1383 }
1384 else
1385 {
1386 if (sameUV)
1387 {
1388 ipl = ipf;
1389 ivl = iv1;
1390 isv1 = isv1;
1391 }
1392 else
1393 {
703a6abd
O
1394 myNbLocat++;
1395 myLocation3d.Bind(myNbLocat,Nodes(Indices(nbnodes)).Transformed(Loc.Transformation()));
1396 ipl = myNbLocat;
7fd59977 1397 }
703a6abd 1398 myVertices.Bind(pEnd,ipl);
7fd59977 1399 }
1400 }
703a6abd
O
1401 NewNodInStruct(nbnodes) = ipl;
1402 theUV = BRepMesh_FastDiscretFace::FindUV(pEnd, uvLast, ipl, gFace, mindist, myLocation2d);
0d88155b 1403 BRepMesh_Vertex vl(theUV,ipl,BRepMesh_Frontier);
7fd59977 1404
703a6abd
O
1405 ivl = myStructure->AddNode(vl);
1406 isvl = myVemap.FindIndex(ivl);
1407 if (isvl == 0) isvl = myVemap.Add(ivl);
7fd59977 1408
703a6abd
O
1409 NewNodes(nbnodes) = isvl;
1410
1411 gp_Pnt2d uv;
1412 BRepMesh_Vertex v;
1413
1414 if (BRep_Tool::SameParameter(theEdge))
7fd59977 1415 {
703a6abd 1416 for (i = 2; i < Indices.Length(); i++)
7fd59977 1417 {
1418 // Record 3d point
703a6abd
O
1419 P3d = Nodes(Indices(i));
1420 if (!Loc.IsIdentity())
1421 P3d.Transform(Loc.Transformation());
1422 myNbLocat++;
1423 myLocation3d.Bind(myNbLocat, P3d);
1424 NewNodInStruct(i) = myNbLocat;
7fd59977 1425 // Record 2d point
703a6abd 1426 uv = theC2d->Value(Param->Value(i));
0d88155b 1427 v.Initialize(uv.Coord(), myNbLocat, BRepMesh_Frontier);
703a6abd
O
1428 iv2 = myStructure->AddNode(v);
1429 isv = myVemap.FindIndex(iv2);
1430 if (isv == 0) isv = myVemap.Add(iv2);
1431 NewNodes(i) = isv;
7fd59977 1432
1433 //add links
1434 if (orEdge == TopAbs_FORWARD)
0d88155b 1435 myStructure->AddLink(BRepMesh_Edge(iv1,iv2,BRepMesh_Frontier));
703a6abd 1436 else if (orEdge == TopAbs_REVERSED)
0d88155b 1437 myStructure->AddLink(BRepMesh_Edge(iv2,iv1,BRepMesh_Frontier));
703a6abd 1438 else if (orEdge == TopAbs_INTERNAL)
0d88155b 1439 myStructure->AddLink(BRepMesh_Edge(iv1,iv2,BRepMesh_Fixed));
703a6abd
O
1440 iv1 = iv2;
1441 }
7fd59977 1442
1443 // last point
1444 if (iv1 != ivl) {
703a6abd 1445 if (orEdge == TopAbs_FORWARD)
0d88155b 1446 myStructure->AddLink(BRepMesh_Edge(iv1,ivl,BRepMesh_Frontier));
703a6abd 1447 else if (orEdge == TopAbs_REVERSED)
0d88155b 1448 myStructure->AddLink(BRepMesh_Edge(ivl,iv1,BRepMesh_Frontier));
703a6abd 1449 else if (orEdge == TopAbs_INTERNAL)
0d88155b 1450 myStructure->AddLink(BRepMesh_Edge(iv1,ivl,BRepMesh_Fixed));
703a6abd
O
1451 }
1452
7fd59977 1453
703a6abd 1454 }
7fd59977 1455 else
1456 {
703a6abd
O
1457 const Standard_Real wFold = Param->Value(Param->Lower());
1458 const Standard_Real wLold = Param->Value(Param->Upper());
1459
1460 Standard_Real wKoef = 1.;
1461 if ((wFold != wFirst || wLold != wLast) && wLold != wFold)
7fd59977 1462 {
703a6abd
O
1463 wKoef = (wLast - wFirst) / (wLold - wFold);
1464 }
1465
1466 BRepAdaptor_Curve cons(theEdge, theFace);
1467 Extrema_LocateExtPC pcos;
1468 pcos.Initialize(cons, cons.FirstParameter(),
1469 cons.LastParameter(), Precision::PConfusion());
1470
1471 Standard_Real wPrev;
1472 Standard_Real wCur = wFirst;
1473 Standard_Real wCurFound = wFirst;
1474 for (i = 2; i < Indices.Length(); i++)
7fd59977 1475 {
1476 // Record 3d point
703a6abd
O
1477 P3d = Nodes(Indices(i));
1478 if (!Loc.IsIdentity())
1479 P3d.Transform(Loc.Transformation());
1480 myNbLocat++;
1481 myLocation3d.Bind(myNbLocat, P3d);
1482 NewNodInStruct(i) = myNbLocat;
7fd59977 1483 // Record 2d point
703a6abd
O
1484 wPrev = wCur;
1485 wCur = wFirst + wKoef*(Param->Value(i) - wFold);
7fd59977 1486 wCurFound += (wCur - wPrev);
703a6abd
O
1487 pcos.Perform(P3d, wCurFound);
1488 if (pcos.IsDone()) wCurFound = pcos.Point().Parameter();
1489 theC2d->D0(wCurFound, uv);
0d88155b 1490 v.Initialize(uv.Coord(), myNbLocat, BRepMesh_Frontier);
703a6abd
O
1491 iv2 = myStructure->AddNode(v);
1492 isv = myVemap.FindIndex(iv2);
1493 if (isv == 0) isv = myVemap.Add(iv2);
1494 NewNodes(i) = isv;
7fd59977 1495
1496
1497 //add links
1498 if (orEdge == TopAbs_FORWARD)
0d88155b 1499 myStructure->AddLink(BRepMesh_Edge(iv1,iv2,BRepMesh_Frontier));
703a6abd 1500 else if (orEdge == TopAbs_REVERSED)
0d88155b 1501 myStructure->AddLink(BRepMesh_Edge(iv2,iv1,BRepMesh_Frontier));
703a6abd 1502 else if (orEdge == TopAbs_INTERNAL)
0d88155b 1503 myStructure->AddLink(BRepMesh_Edge(iv1,iv2,BRepMesh_Fixed));
703a6abd
O
1504 iv1 = iv2;
1505 }
7fd59977 1506
1507 // last point
1508 if (iv1 != ivl) {
703a6abd 1509 if (orEdge == TopAbs_FORWARD)
0d88155b 1510 myStructure->AddLink(BRepMesh_Edge(iv1,ivl,BRepMesh_Frontier));
703a6abd 1511 else if (orEdge == TopAbs_REVERSED)
0d88155b 1512 myStructure->AddLink(BRepMesh_Edge(ivl,iv1,BRepMesh_Frontier));
703a6abd 1513 else if (orEdge == TopAbs_INTERNAL)
0d88155b 1514 myStructure->AddLink(BRepMesh_Edge(iv1,ivl,BRepMesh_Fixed));
703a6abd
O
1515 }
1516 }
1517
1518 Handle(Poly_PolygonOnTriangulation) P1 =
7fd59977 1519 new Poly_PolygonOnTriangulation(NewNodes, Param->Array1());
703a6abd
O
1520 P1->Deflection(theDefEdge);
1521 if (myInternaledges.IsBound(theEdge))
7fd59977 1522 {
703a6abd
O
1523 BRepMesh_PairOfPolygon& pair = myInternaledges.ChangeFind(theEdge);
1524 if (theEdge.Orientation() == TopAbs_REVERSED)
7fd59977 1525 pair.Append(P1);
1526 else
1527 pair.Prepend(P1);
703a6abd
O
1528 }
1529 else
7fd59977 1530 {
703a6abd
O
1531 BRepMesh_PairOfPolygon pair1;
1532 pair1.Append(P1);
1533 myInternaledges.Bind(theEdge, pair1);
1534 }
1535
1536 Handle(Poly_PolygonOnTriangulation) P2 =
7fd59977 1537 new Poly_PolygonOnTriangulation(NewNodInStruct, Param->Array1());
703a6abd
O
1538 P2->Deflection(theDefEdge);
1539 BRepMesh_PairOfPolygon pair;
1540 pair.Append(P2);
1541 myEdges.Bind(theEdge, pair);
1542
1543 found = Standard_True;
7fd59977 1544 }
1545 else
1546 {
703a6abd
O
1547 BRep_Builder B;
1548 B.UpdateEdge(theEdge,NullPoly,T,Loc);
1549 B.UpdateFace(theFace,TNull);
7fd59977 1550 }
1551 }
1552 else if (!T.IsNull() && !T->HasUVNodes())
1553 {
1554 BRep_Builder B;
703a6abd
O
1555 B.UpdateEdge(theEdge,NullPoly,T,Loc);
1556 B.UpdateFace(theFace,TNull);
7fd59977 1557 }
1558 }
1559 while (!Poly.IsNull());
1560
1561 return found;
1562}
1563
1564//=======================================================================
1565//function : output
1566//purpose :
1567//=======================================================================
1568Standard_Integer BRepMesh_FastDiscret::NbTriangles() const
1569{
703a6abd 1570 return myStructure->NbElements();
7fd59977 1571}
1572
1573//=======================================================================
1574//function : Triangle
1575//purpose :
1576//=======================================================================
1577
1578const BRepMesh_Triangle& BRepMesh_FastDiscret::Triangle
1579 (const Standard_Integer Index) const
1580{
703a6abd 1581 return myStructure->GetElement(Index);
7fd59977 1582}
1583
1584//=======================================================================
1585//function : NbEdges
1586//purpose :
1587//=======================================================================
1588
1589Standard_Integer BRepMesh_FastDiscret::NbEdges() const
1590{
703a6abd 1591 return myStructure->NbLinks();
7fd59977 1592}
1593
1594//=======================================================================
1595//function : Edge
1596//purpose :
1597//=======================================================================
1598
1599const BRepMesh_Edge& BRepMesh_FastDiscret::Edge(const Standard_Integer Index) const
1600{
703a6abd 1601 return myStructure->GetLink(Index);
7fd59977 1602}
1603
1604//=======================================================================
1605//function : NbVertices
1606//purpose :
1607//=======================================================================
1608
1609Standard_Integer BRepMesh_FastDiscret::NbVertices() const
1610{
703a6abd 1611 return myStructure->NbNodes();
7fd59977 1612}
1613
1614//=======================================================================
1615//function : Vertex
1616//purpose :
1617//=======================================================================
1618
1619const BRepMesh_Vertex& BRepMesh_FastDiscret::Vertex
1620 (const Standard_Integer Index) const
1621{
703a6abd 1622 return myStructure->GetNode(Index);
7fd59977 1623}
1624
1625//=======================================================================
1626//function : Pnt
1627//purpose :
1628//=======================================================================
1629
1630const gp_Pnt& BRepMesh_FastDiscret::Pnt(const Standard_Integer Index) const
1631{
703a6abd 1632 return myLocation3d(myStructure->GetNode(Index).Location3d());
7fd59977 1633}
1634
1635//=======================================================================
1636//function : VerticesOfDomain
1637//purpose :
1638//=======================================================================
1639
0d88155b 1640void BRepMesh_FastDiscret::VerticesOfDomain(BRepMesh_MapOfInteger& Indices) const
7fd59977 1641{
1642 Indices.Clear();
1643
1644 // recuperate from the map of edges.
0d88155b 1645 const BRepMesh_MapOfInteger& edmap = myStructure->LinkOfDomain();
7fd59977 1646
1647 // iterator on edges.
0d88155b 1648 BRepMesh_MapOfInteger::Iterator iter(edmap);
7fd59977 1649
1650 Standard_Integer ind_edge;
1651 for (iter.Reset(); iter.More(); iter.Next()) {
1652 ind_edge = iter.Key();
1653 const BRepMesh_Edge& Ed = Edge(ind_edge);
1654 Indices.Add(Ed.FirstNode());
1655 Indices.Add(Ed.LastNode());
1656 }
1657}
1658
7fd59977 1659BRepMesh_Status BRepMesh_FastDiscret::CurrentFaceStatus() const
1660{
703a6abd 1661 return myFacestate;
7fd59977 1662}
1663
1664//=======================================================================
1665//function : GetFaceAttribute
1666//purpose :
1667//=======================================================================
1668
703a6abd
O
1669Standard_Boolean BRepMesh_FastDiscret::GetFaceAttribute(const TopoDS_Face& theFace,
1670 Handle(BRepMesh_FaceAttribute)& theFattrib) const
7fd59977 1671{
703a6abd 1672 if(myMapattrib.IsBound(theFace))
7fd59977 1673 {
703a6abd 1674 theFattrib = myMapattrib(theFace);
7fd59977 1675 return Standard_True;
1676 }
1677 return Standard_False;
1678}
1679
1680//=======================================================================
1681//function : RemoveFaceAttribute
1682//purpose :
1683//=======================================================================
1684
1685void BRepMesh_FastDiscret::RemoveFaceAttribute(const TopoDS_Face& theFace)
1686{
703a6abd
O
1687 if(myMapattrib.IsBound(theFace))
1688 myMapattrib.UnBind(theFace);
7fd59977 1689}