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 | |
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 | ||
282 | void 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 |
306 | void 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 | //======================================================================= | |
736 | static 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 |
790 | void 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 |
1260 | Standard_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 | //======================================================================= | |
1568 | Standard_Integer BRepMesh_FastDiscret::NbTriangles() const | |
1569 | { | |
703a6abd | 1570 | return myStructure->NbElements(); |
7fd59977 | 1571 | } |
1572 | ||
1573 | //======================================================================= | |
1574 | //function : Triangle | |
1575 | //purpose : | |
1576 | //======================================================================= | |
1577 | ||
1578 | const 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 | ||
1589 | Standard_Integer BRepMesh_FastDiscret::NbEdges() const | |
1590 | { | |
703a6abd | 1591 | return myStructure->NbLinks(); |
7fd59977 | 1592 | } |
1593 | ||
1594 | //======================================================================= | |
1595 | //function : Edge | |
1596 | //purpose : | |
1597 | //======================================================================= | |
1598 | ||
1599 | const 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 | ||
1609 | Standard_Integer BRepMesh_FastDiscret::NbVertices() const | |
1610 | { | |
703a6abd | 1611 | return myStructure->NbNodes(); |
7fd59977 | 1612 | } |
1613 | ||
1614 | //======================================================================= | |
1615 | //function : Vertex | |
1616 | //purpose : | |
1617 | //======================================================================= | |
1618 | ||
1619 | const 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 | ||
1630 | const 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 | 1640 | void 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 | 1659 | BRepMesh_Status BRepMesh_FastDiscret::CurrentFaceStatus() const |
1660 | { | |
703a6abd | 1661 | return myFacestate; |
7fd59977 | 1662 | } |
1663 | ||
1664 | //======================================================================= | |
1665 | //function : GetFaceAttribute | |
1666 | //purpose : | |
1667 | //======================================================================= | |
1668 | ||
703a6abd O |
1669 | Standard_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 | ||
1685 | void BRepMesh_FastDiscret::RemoveFaceAttribute(const TopoDS_Face& theFace) | |
1686 | { | |
703a6abd O |
1687 | if(myMapattrib.IsBound(theFace)) |
1688 | myMapattrib.UnBind(theFace); | |
7fd59977 | 1689 | } |