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