Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 1993-12-15 |
2 | // Created by: Isabelle GRIGNON | |
3 | // Copyright (c) 1993-1999 Matra Datavision | |
973c2be1 | 4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e | 5 | // |
973c2be1 | 6 | // This file is part of Open CASCADE Technology software library. |
b311480e | 7 | // |
973c2be1 | 8 | // This library is free software; you can redistribute it and / or modify it |
9 | // under the terms of the GNU Lesser General Public version 2.1 as published | |
10 | // by the Free Software Foundation, with special exception defined in the file | |
11 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT | |
12 | // distribution for complete text of the license and disclaimer of any warranty. | |
b311480e | 13 | // |
973c2be1 | 14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. | |
7fd59977 | 16 | |
17 | #include <ChFi3d_Builder.jxx> | |
18 | ||
19 | #include <Precision.hxx> | |
20 | ||
21 | #include <gp_Pnt.hxx> | |
22 | #include <gp_Vec.hxx> | |
23 | ||
24 | #include <TopoDS.hxx> | |
25 | #include <TopoDS_Shape.hxx> | |
26 | #include <TopoDS_Face.hxx> | |
27 | #include <TopoDS_Edge.hxx> | |
28 | #include <TopoDS_Vertex.hxx> | |
29 | ||
30 | #include <BRepAdaptor_Curve.hxx> | |
31 | #include <BRepAdaptor_Surface.hxx> | |
32 | #include <BRepLProp_SLProps.hxx> | |
33 | ||
34 | #include <TopAbs.hxx> | |
35 | #include <TopAbs_ShapeEnum.hxx> | |
36 | #include <TopAbs_Orientation.hxx> | |
37 | ||
38 | #include <BRep_Tool.hxx> | |
39 | #include <TopExp.hxx> | |
40 | #include <TopTools_ListIteratorOfListOfShape.hxx> | |
41 | #include <TopOpeBRepDS_Surface.hxx> | |
42 | ||
43 | #include <ChFiDS_ErrorStatus.hxx> | |
44 | #include <ChFiDS_State.hxx> | |
45 | #include <ChFiDS_Spine.hxx> | |
46 | #include <ChFiDS_FilSpine.hxx> | |
47 | #include <ChFiDS_HData.hxx> | |
48 | #include <ChFiDS_SurfData.hxx> | |
49 | #include <ChFiDS_Regul.hxx> | |
50 | #include <ChFiDS_ListIteratorOfRegularities.hxx> | |
51 | #include <ChFiDS_ListIteratorOfListOfStripe.hxx> | |
52 | ||
53 | #include <ChFi3d.hxx> | |
54 | #include <ChFi3d_Builder_0.hxx> | |
55 | ||
56 | #include <LocalAnalysis_SurfaceContinuity.hxx> | |
57 | #include <TopOpeBRepTool_TOOL.hxx> | |
58 | ||
59 | #ifdef DEB | |
60 | extern Standard_Boolean ChFi3d_GetcontextFORCEBLEND(); | |
61 | #endif | |
62 | ||
63 | static TopOpeBRepDS_BuildTool mkbuildtool() | |
64 | { | |
65 | TopOpeBRepTool_GeomTool GT2(TopOpeBRepTool_BSPLINE1, | |
66 | Standard_True, | |
67 | Standard_False, | |
68 | Standard_False); | |
69 | TopOpeBRepDS_BuildTool BT(GT2); | |
70 | BT.OverWrite(Standard_False); | |
71 | BT.Translate(Standard_False); | |
72 | return BT; | |
73 | } | |
74 | ||
75 | // Modified by Sergey KHROMOV - Tue Dec 18 18:02:55 2001 Begin | |
76 | Standard_Boolean isTangentFaces(const TopoDS_Edge &theEdge, | |
77 | const TopoDS_Face &theFace1, | |
78 | const TopoDS_Face &theFace2) | |
79 | { | |
80 | if (BRep_Tool::Continuity( theEdge, theFace1, theFace2 ) != GeomAbs_C0) | |
81 | return Standard_True; | |
82 | ||
83 | Standard_Real aFirst; | |
84 | Standard_Real aLast; | |
85 | ||
86 | // Obtaining of pcurves of edge on two faces. | |
87 | const Handle(Geom2d_Curve) aC2d1 = BRep_Tool::CurveOnSurface | |
88 | (theEdge, theFace1, aFirst, aLast); | |
89 | const Handle(Geom2d_Curve) aC2d2 = BRep_Tool::CurveOnSurface | |
90 | (theEdge, theFace2, aFirst, aLast); | |
91 | if (aC2d1.IsNull() || aC2d2.IsNull()) | |
92 | return Standard_False; | |
93 | ||
94 | // Obtaining of two surfaces from adjacent faces. | |
95 | Handle(Geom_Surface) aSurf1 = BRep_Tool::Surface(theFace1); | |
96 | Handle(Geom_Surface) aSurf2 = BRep_Tool::Surface(theFace2); | |
97 | ||
98 | if (aSurf1.IsNull() || aSurf2.IsNull()) | |
99 | return Standard_False; | |
100 | ||
101 | // Computation of the number of samples on the edge. | |
102 | BRepAdaptor_Surface aBAS1(theFace1); | |
103 | BRepAdaptor_Surface aBAS2(theFace2); | |
104 | Handle(BRepAdaptor_HSurface) aBAHS1 = new BRepAdaptor_HSurface(aBAS1); | |
105 | Handle(BRepAdaptor_HSurface) aBAHS2 = new BRepAdaptor_HSurface(aBAS2); | |
106 | Handle(BRepTopAdaptor_TopolTool) aTool1 = new BRepTopAdaptor_TopolTool(aBAHS1); | |
107 | Handle(BRepTopAdaptor_TopolTool) aTool2 = new BRepTopAdaptor_TopolTool(aBAHS2); | |
108 | Standard_Integer aNbSamples1 = aTool1->NbSamples(); | |
109 | Standard_Integer aNbSamples2 = aTool2->NbSamples(); | |
110 | Standard_Integer aNbSamples = Max(aNbSamples1, aNbSamples2); | |
111 | ||
112 | ||
113 | // Computation of the continuity. | |
114 | Standard_Real aPar; | |
115 | Standard_Real aDelta = (aLast - aFirst)/(aNbSamples - 1); | |
116 | Standard_Integer i, nbNotDone = 0; | |
117 | ||
118 | for (i = 1, aPar = aFirst; i <= aNbSamples; i++, aPar += aDelta) { | |
119 | if (i == aNbSamples) aPar = aLast; | |
120 | ||
121 | LocalAnalysis_SurfaceContinuity aCont(aC2d1, aC2d2, aPar, | |
122 | aSurf1, aSurf2, GeomAbs_G1, | |
123 | 0.001, 0.001, 0.1, 0.1, 0.1); | |
124 | if (!aCont.IsDone()) | |
125 | { | |
126 | nbNotDone++; | |
127 | continue; | |
128 | } | |
129 | if (!aCont.IsG1()) | |
130 | return Standard_False; | |
131 | } | |
132 | ||
133 | if (nbNotDone == aNbSamples) | |
134 | return Standard_False; | |
135 | ||
136 | //Compare normals of tangent faces in the middle point | |
137 | Standard_Real MidPar = (aFirst + aLast)/2.; | |
138 | gp_Pnt2d uv1 = aC2d1->Value(MidPar); | |
139 | gp_Pnt2d uv2 = aC2d2->Value(MidPar); | |
140 | gp_Dir normal1, normal2; | |
141 | TopOpeBRepTool_TOOL::Nt( uv1, theFace1, normal1 ); | |
142 | TopOpeBRepTool_TOOL::Nt( uv2, theFace2, normal2 ); | |
143 | Standard_Real dot = normal1.Dot(normal2); | |
144 | if (dot < 0.) | |
145 | return Standard_False; | |
146 | return Standard_True; | |
147 | } | |
148 | // Modified by Sergey KHROMOV - Tue Dec 18 18:02:56 2001 End | |
149 | ||
150 | //======================================================================= | |
151 | //function : ChFi3d_Builder | |
152 | //purpose : | |
153 | //======================================================================= | |
154 | ChFi3d_Builder::ChFi3d_Builder(const TopoDS_Shape& S, | |
155 | const Standard_Real Ta) : | |
156 | done(Standard_False), myShape(S) | |
157 | { | |
158 | myDS = new TopOpeBRepDS_HDataStructure(); | |
159 | myCoup = new TopOpeBRepBuild_HBuilder(mkbuildtool()); | |
160 | myEFMap.Fill(S,TopAbs_EDGE,TopAbs_FACE); | |
161 | myESoMap.Fill(S,TopAbs_EDGE,TopAbs_SOLID); | |
162 | myEShMap.Fill(S,TopAbs_EDGE,TopAbs_SHELL); | |
163 | myVFMap.Fill(S,TopAbs_VERTEX,TopAbs_FACE); | |
164 | myVEMap.Fill(S,TopAbs_VERTEX,TopAbs_EDGE); | |
165 | SetParams(Ta,1.e-4,1.e-5,1.e-4,1.e-5,1.e-3); | |
166 | SetContinuity(GeomAbs_C1, Ta); | |
167 | } | |
168 | ||
169 | //======================================================================= | |
170 | //function : SetParams | |
171 | //purpose : | |
172 | //======================================================================= | |
173 | ||
174 | void ChFi3d_Builder::SetParams(const Standard_Real Tang, | |
175 | const Standard_Real Tesp, | |
176 | const Standard_Real T2d, | |
177 | const Standard_Real TApp3d, | |
178 | const Standard_Real TolApp2d, | |
179 | const Standard_Real Fleche) | |
180 | { | |
181 | angular = Tang; | |
182 | tolesp = Tesp; | |
183 | tol2d = T2d; | |
184 | tolapp3d = TApp3d; | |
185 | tolapp2d = TolApp2d; | |
186 | fleche = Fleche; | |
187 | } | |
188 | ||
189 | //======================================================================= | |
190 | //function : SetContinuity | |
191 | //purpose : | |
192 | //======================================================================= | |
193 | ||
194 | void ChFi3d_Builder::SetContinuity(const GeomAbs_Shape InternalContinuity, | |
195 | const Standard_Real AngularTolerance) | |
196 | { | |
197 | myConti = InternalContinuity; | |
198 | tolappangle = AngularTolerance; | |
199 | } | |
200 | ||
201 | //======================================================================= | |
202 | //function : IsDone | |
203 | //purpose : | |
204 | //======================================================================= | |
205 | ||
206 | Standard_Boolean ChFi3d_Builder::IsDone() const | |
207 | { | |
208 | return done; | |
209 | } | |
210 | ||
211 | //======================================================================= | |
212 | //function : Shape | |
213 | //purpose : | |
214 | //======================================================================= | |
215 | ||
216 | TopoDS_Shape ChFi3d_Builder::Shape()const | |
217 | { | |
218 | Standard_NoSuchObject_Raise_if(!done,""); | |
219 | return myShapeResult; | |
220 | } | |
221 | ||
222 | //======================================================================= | |
223 | //function : NbFaultyContours | |
224 | //purpose : | |
225 | //======================================================================= | |
226 | ||
227 | Standard_Integer ChFi3d_Builder::NbFaultyContours() const | |
228 | { | |
229 | return badstripes.Extent(); | |
230 | } | |
231 | ||
232 | //======================================================================= | |
233 | //function : FaultyContour | |
234 | //purpose : | |
235 | //======================================================================= | |
236 | ||
237 | Standard_Integer ChFi3d_Builder::FaultyContour(const Standard_Integer I) const | |
238 | { | |
239 | ChFiDS_ListIteratorOfListOfStripe itel; | |
240 | Standard_Integer k = 0; | |
241 | Handle(ChFiDS_Stripe) st; | |
242 | for (itel.Initialize(badstripes);itel.More(); itel.Next()) { | |
243 | k += 1; | |
244 | if(k == I) { | |
245 | st = itel.Value(); | |
246 | break; | |
247 | } | |
248 | } | |
249 | if(st.IsNull()) return 0; | |
250 | k = 0; | |
251 | for (itel.Initialize(myListStripe);itel.More(); itel.Next()) { | |
252 | k += 1; | |
253 | if(st == itel.Value()) return k; | |
254 | } | |
255 | return 0; | |
256 | } | |
257 | ||
258 | //======================================================================= | |
259 | //function : NbComputedSurfaces | |
260 | //purpose : | |
261 | //======================================================================= | |
262 | ||
263 | Standard_Integer ChFi3d_Builder::NbComputedSurfaces(const Standard_Integer IC) const | |
264 | { | |
265 | ChFiDS_ListIteratorOfListOfStripe itel; | |
266 | Standard_Integer k = 0; | |
267 | Handle(ChFiDS_Stripe) st; | |
268 | for (itel.Initialize(myListStripe);itel.More(); itel.Next()) { | |
269 | k += 1; | |
270 | if(k == IC) { | |
271 | st = itel.Value(); | |
272 | break; | |
273 | } | |
274 | } | |
275 | if(st.IsNull()) return 0; | |
276 | if(st->Spine().IsNull()) return 0; | |
277 | Handle(ChFiDS_HData) hd = st->SetOfSurfData(); | |
278 | if(hd.IsNull()) return 0; | |
279 | return hd->Length(); | |
280 | } | |
281 | ||
282 | //======================================================================= | |
283 | //function : ComputedSurface | |
284 | //purpose : | |
285 | //======================================================================= | |
286 | ||
287 | Handle(Geom_Surface) ChFi3d_Builder::ComputedSurface(const Standard_Integer IC, | |
288 | const Standard_Integer IS) const | |
289 | { | |
290 | ChFiDS_ListIteratorOfListOfStripe itel; | |
291 | Standard_Integer k = 0; | |
292 | Handle(ChFiDS_Stripe) st; | |
293 | for (itel.Initialize(myListStripe);itel.More(); itel.Next()) { | |
294 | k += 1; | |
295 | if(k == IC) { | |
296 | st = itel.Value(); | |
297 | break; | |
298 | } | |
299 | } | |
300 | Handle(ChFiDS_HData) hd = st->SetOfSurfData(); | |
301 | Standard_Integer isurf=hd->Value(IS)->Surf(); | |
302 | return myDS->Surface(isurf).Surface(); | |
303 | } | |
304 | ||
305 | //======================================================================= | |
306 | //function : NbFaultyVertices | |
307 | //purpose : | |
308 | //======================================================================= | |
309 | ||
310 | Standard_Integer ChFi3d_Builder::NbFaultyVertices() const | |
311 | { | |
312 | return badvertices.Extent(); | |
313 | } | |
314 | ||
315 | //======================================================================= | |
316 | //function : FaultyVertex | |
317 | //purpose : | |
318 | //======================================================================= | |
319 | ||
320 | TopoDS_Vertex ChFi3d_Builder::FaultyVertex(const Standard_Integer IV) const | |
321 | { | |
322 | TopTools_ListIteratorOfListOfShape it; | |
323 | TopoDS_Vertex V; | |
324 | Standard_Integer k = 0; | |
325 | for(it.Initialize(badvertices);it.More(); it.Next()) { | |
326 | k += 1; | |
327 | if(k == IV) { | |
328 | V = TopoDS::Vertex(it.Value()); | |
329 | break; | |
330 | } | |
331 | } | |
332 | return V; | |
333 | } | |
334 | ||
335 | //======================================================================= | |
336 | //function : HasResult | |
337 | //purpose : | |
338 | //======================================================================= | |
339 | ||
340 | Standard_Boolean ChFi3d_Builder::HasResult() const | |
341 | { | |
342 | return hasresult; | |
343 | } | |
344 | ||
345 | //======================================================================= | |
346 | //function : BadShape | |
347 | //purpose : | |
348 | //======================================================================= | |
349 | ||
350 | TopoDS_Shape ChFi3d_Builder::BadShape()const | |
351 | { | |
352 | Standard_NoSuchObject_Raise_if(!hasresult,""); | |
353 | return badShape; | |
354 | } | |
355 | ||
356 | //======================================================================= | |
357 | //function : StripeStatus | |
358 | //purpose : | |
359 | //======================================================================= | |
360 | ||
361 | ChFiDS_ErrorStatus ChFi3d_Builder::StripeStatus(const Standard_Integer IC)const | |
362 | { | |
363 | ChFiDS_ListIteratorOfListOfStripe itel; | |
364 | Standard_Integer k =0; | |
365 | Handle(ChFiDS_Stripe) st; | |
366 | for (itel.Initialize(myListStripe);itel.More(); itel.Next()) { | |
367 | k += 1; | |
368 | if(k == IC) { | |
369 | st = itel.Value(); | |
370 | break; | |
371 | } | |
372 | } | |
373 | ChFiDS_ErrorStatus stat=st->Spine()->ErrorStatus(); | |
374 | return stat; | |
375 | } | |
376 | ||
377 | //======================================================================= | |
378 | //function : Builder | |
379 | //purpose : | |
380 | //======================================================================= | |
381 | ||
382 | Handle(TopOpeBRepBuild_HBuilder) ChFi3d_Builder::Builder()const | |
383 | { | |
384 | return myCoup; | |
385 | } | |
386 | ||
387 | //======================================================================= | |
388 | //function : ChFi3d_FaceTangency | |
81bba717 | 389 | //purpose : determine if the faces opposing to edges are tangent |
390 | // to go from opposing faces on e0 to opposing faces | |
391 | // on e1, consider all faces starting at a common top. | |
7fd59977 | 392 | //======================================================================= |
393 | ||
394 | Standard_Boolean ChFi3d_Builder::FaceTangency(const TopoDS_Edge& E0, | |
395 | const TopoDS_Edge& E1, | |
396 | const TopoDS_Vertex& V) const | |
397 | { | |
398 | TopTools_ListIteratorOfListOfShape It,Jt; | |
399 | TopoDS_Edge Ec; | |
400 | Standard_Integer Nbf; | |
401 | TopoDS_Face F[2]; | |
402 | ||
81bba717 | 403 | //It is checked if the connection is not on a regular edge. |
7fd59977 | 404 | for (It.Initialize(myEFMap(E1)), Nbf= 0 ;It.More();It.Next(), Nbf++) { |
405 | if (Nbf>1) | |
406 | Standard_ConstructionError::Raise("ChFi3d_Builder:only 2 faces"); | |
407 | F[Nbf] = TopoDS::Face(It.Value()); | |
408 | } | |
409 | if(Nbf < 2) return Standard_False; | |
410 | // Modified by Sergey KHROMOV - Fri Dec 21 17:44:19 2001 Begin | |
411 | //if (BRep_Tool::Continuity(E1,F[0],F[1]) != GeomAbs_C0) { | |
412 | if (isTangentFaces(E1,F[0],F[1])) { | |
413 | // Modified by Sergey KHROMOV - Fri Dec 21 17:44:21 2001 End | |
414 | return Standard_False; | |
415 | } | |
416 | ||
417 | for (Jt.Initialize(myVEMap(V));Jt.More();Jt.Next()) { | |
418 | Ec = TopoDS::Edge(Jt.Value()); | |
419 | if (!Ec.IsSame(E0) && !Ec.IsSame(E1) && | |
420 | Ec.Orientation() != TopAbs_INTERNAL && | |
421 | Ec.Orientation() != TopAbs_EXTERNAL && | |
422 | !BRep_Tool::Degenerated(Ec)) { | |
423 | for (It.Initialize(myEFMap(Ec)), Nbf= 0 ;It.More();It.Next(), Nbf++) { | |
424 | if (Nbf>1) | |
425 | Standard_ConstructionError::Raise("ChFi3d_Builder:only 2 faces"); | |
426 | F[Nbf] = TopoDS::Face(It.Value()); | |
427 | } | |
428 | if(Nbf < 2) return Standard_False; | |
429 | // Modified by Sergey KHROMOV - Tue Dec 18 18:10:40 2001 Begin | |
430 | // if (BRep_Tool::Continuity(Ec,F[0],F[1]) < GeomAbs_G1) { | |
431 | if (!isTangentFaces(Ec,F[0],F[1])) { | |
432 | // Modified by Sergey KHROMOV - Tue Dec 18 18:10:41 2001 End | |
433 | return Standard_False; | |
434 | } | |
435 | } | |
436 | } | |
437 | return Standard_True; | |
438 | ||
439 | } | |
440 | ||
441 | ||
442 | //======================================================================= | |
443 | //function : TangentExtremity | |
81bba717 | 444 | //purpose : Test if 2 faces are tangent at the end of an edge |
7fd59977 | 445 | //======================================================================= |
446 | static Standard_Boolean TangentExtremity(const TopoDS_Vertex& V, | |
447 | const TopoDS_Edge& E, | |
448 | const Handle(BRepAdaptor_HSurface)& hs1, | |
449 | const Handle(BRepAdaptor_HSurface)& hs2, | |
450 | // const Standard_Real t3d, | |
451 | const Standard_Real tang) | |
452 | { | |
453 | TopoDS_Face f1 = hs1->ChangeSurface().Face(); | |
454 | TopAbs_Orientation O1 = f1.Orientation(); | |
455 | f1.Orientation(TopAbs_FORWARD); | |
456 | TopoDS_Face f2 = hs2->ChangeSurface().Face(); | |
457 | TopAbs_Orientation O2 = f2.Orientation(); | |
458 | f2.Orientation(TopAbs_FORWARD); | |
459 | TopoDS_Edge e1 = E, e2 = E; | |
460 | e1.Orientation(TopAbs_FORWARD); | |
461 | e2.Orientation(TopAbs_FORWARD); | |
462 | if(f1.IsSame(f2) && BRep_Tool::IsClosed(e1,f1)) | |
463 | e2.Orientation(TopAbs_REVERSED); | |
464 | Standard_Real p1 = BRep_Tool::Parameter(V,e1,f1); | |
465 | Standard_Real p2 = BRep_Tool::Parameter(V,e2,f2); | |
466 | Standard_Real u,v,f,l, Eps = 1.e-9; | |
467 | gp_Vec n1, n2;// gp_Pnt pt1,pt2; | |
468 | Handle(Geom2d_Curve) pc1 = BRep_Tool::CurveOnSurface(e1,f1,f,l); | |
469 | pc1->Value(p1).Coord(u,v); | |
470 | BRepLProp_SLProps theProp1(hs1->ChangeSurface(), u, v, 1, Eps); | |
471 | if (theProp1.IsNormalDefined()) { | |
472 | n1.SetXYZ(theProp1.Normal().XYZ()); | |
473 | if (O1 == TopAbs_REVERSED) n1.Reverse(); | |
474 | } | |
81bba717 | 475 | else return Standard_False; // It is not known... |
7fd59977 | 476 | |
477 | ||
478 | Handle(Geom2d_Curve) pc2 = BRep_Tool::CurveOnSurface(e2,f2,f,l); | |
479 | pc2->Value(p2).Coord(u,v); | |
480 | BRepLProp_SLProps theProp2(hs2->ChangeSurface(), u, v, 1, Eps); | |
481 | if (theProp2.IsNormalDefined()) { | |
482 | n2.SetXYZ(theProp2.Normal().XYZ()); | |
483 | if(O2 == TopAbs_REVERSED) n2.Reverse(); | |
484 | } | |
81bba717 | 485 | else return Standard_False; // It is not known... |
7fd59977 | 486 | |
487 | return (n1.Angle(n2) < tang); | |
488 | } | |
489 | ||
490 | //======================================================================= | |
491 | //function : TangentOnVertex | |
81bba717 | 492 | //purpose : Test if support faces of an edge are tangent at end. |
7fd59977 | 493 | //======================================================================= |
494 | static Standard_Boolean TangentOnVertex(const TopoDS_Vertex& V, | |
495 | const TopoDS_Edge& E, | |
496 | const ChFiDS_Map& EFMap, | |
497 | const Standard_Real tang) | |
498 | { | |
499 | TopoDS_Face ff1,ff2; | |
500 | ChFi3d_conexfaces(E,ff1,ff2,EFMap); | |
501 | if(ff1.IsNull() || ff2.IsNull()) return 0; | |
502 | Handle(BRepAdaptor_HSurface) S1 = new (BRepAdaptor_HSurface)(ff1); | |
503 | Handle(BRepAdaptor_HSurface) S2 = new (BRepAdaptor_HSurface)(ff2); | |
504 | return TangentExtremity(V, E, S1, S2, tang); | |
505 | } | |
506 | ||
507 | //======================================================================= | |
508 | //function : PerformExtremity | |
81bba717 | 509 | //purpose : In case if PerformElement returned BreakPoint at one or |
510 | // another extremity, it is attempted to refine | |
511 | // depending on concavities between neighbour faces of the top. | |
7fd59977 | 512 | //======================================================================= |
513 | ||
514 | void ChFi3d_Builder::PerformExtremity (const Handle(ChFiDS_Spine)& Spine) | |
515 | { | |
516 | for(Standard_Integer ii = 1; ii <= 2; ii++){ | |
517 | TopoDS_Edge E[3],Ec; | |
518 | TopoDS_Vertex V; | |
519 | ChFiDS_State sst; | |
520 | Standard_Integer iedge; | |
521 | Handle(BRepAdaptor_HSurface) hs1,hs2; | |
522 | if(ii == 1){ | |
523 | sst = Spine->FirstStatus(); | |
524 | iedge = 1; | |
525 | V = Spine->FirstVertex(); | |
526 | } | |
527 | else{ | |
528 | sst = Spine->LastStatus(); | |
529 | iedge = Spine->NbEdges(); | |
530 | E[0] = Spine->Edges(iedge); | |
531 | V = Spine->LastVertex(); | |
532 | } | |
81bba717 | 533 | //Before all it is checked if the tangency is not dead. |
7fd59977 | 534 | E[0] = Spine->Edges(iedge); |
535 | ConexFaces (Spine,iedge,0,hs1,hs2); | |
536 | if(TangentExtremity(V,E[0],hs1,hs2,angular)){ | |
537 | Spine->SetTangencyExtremity(Standard_True, (ii == 1)); | |
538 | } | |
539 | ||
540 | if(sst == ChFiDS_BreakPoint){ | |
541 | TopTools_ListIteratorOfListOfShape It;//,Jt; | |
542 | Standard_Integer i = 0, j; | |
543 | Standard_Boolean sommetpourri = Standard_False; | |
544 | for (It.Initialize(myVEMap(V));It.More();It.Next()){ | |
545 | Ec = TopoDS::Edge(It.Value()); | |
546 | Standard_Boolean bonedge = !BRep_Tool::Degenerated(Ec); | |
547 | if(bonedge){ | |
548 | TopoDS_Vertex v1,v2; | |
549 | TopExp::Vertices(Ec,v1,v2); | |
550 | Standard_Boolean eclosed = v1.IsSame(v2); | |
551 | Standard_Integer nboc = 0; | |
552 | for(j = 0; j <= i && bonedge; j++){ | |
553 | if(!eclosed) bonedge = !Ec.IsSame(E[j]); | |
554 | else if(Ec.IsSame(E[j])){ | |
555 | nboc++; | |
556 | bonedge = nboc<2; | |
557 | } | |
558 | } | |
559 | } | |
560 | if(bonedge){ | |
561 | if( i < 2 ){ | |
562 | i++; | |
563 | E[i] = Ec; | |
564 | } | |
565 | else{ | |
566 | #ifdef DEB | |
81bba717 | 567 | cout<<"top has more than 3 edges"<<endl; |
7fd59977 | 568 | #endif |
569 | sommetpourri = Standard_True; | |
570 | break; | |
571 | } | |
572 | } | |
573 | } | |
574 | if(i != 2) sommetpourri = Standard_True; | |
575 | if(!sommetpourri){ | |
576 | sst = ChFi3d_EdgeState(E,myEFMap); | |
577 | } | |
578 | if(ii==1)Spine->SetFirstStatus(sst); | |
579 | else Spine->SetLastStatus(sst); | |
580 | } | |
581 | } | |
582 | ||
7fd59977 | 583 | if (!Spine->IsPeriodic()) { |
584 | TopTools_ListIteratorOfListOfShape It,Jt; | |
585 | Standard_Integer nbf = 0, jf = 0; | |
586 | for (It.Initialize(myVFMap(Spine->FirstVertex())); It.More(); It.Next()){ | |
587 | jf++; | |
588 | Standard_Integer kf = 1; | |
589 | const TopoDS_Shape& cur = It.Value(); | |
590 | for (Jt.Initialize(myVFMap(Spine->FirstVertex())); Jt.More() && (kf < jf); Jt.Next(), kf++){ | |
591 | if(cur.IsSame(Jt.Value())) break; | |
592 | } | |
593 | if(kf == jf) nbf++; | |
594 | } | |
595 | if(nbf>3) { | |
596 | Spine->SetFirstStatus(ChFiDS_BreakPoint); | |
597 | #if DEB | |
81bba717 | 598 | cout<<"top has : "<<nbf<<" faces."<<endl; |
7fd59977 | 599 | #endif |
600 | } | |
601 | nbf = 0, jf = 0; | |
602 | for (It.Initialize(myVFMap(Spine->LastVertex())); It.More(); It.Next()){ | |
603 | jf++; | |
604 | Standard_Integer kf = 1; | |
605 | const TopoDS_Shape& cur = It.Value(); | |
606 | for (Jt.Initialize(myVFMap(Spine->LastVertex())); Jt.More() && (kf < jf); Jt.Next(), kf++){ | |
607 | if(cur.IsSame(Jt.Value())) break; | |
608 | } | |
609 | if(kf == jf) nbf++; | |
610 | } | |
611 | if(nbf>3) { | |
612 | Spine->SetLastStatus(ChFiDS_BreakPoint); | |
613 | #if DEB | |
81bba717 | 614 | cout<<"top has : "<<nbf<<" faces."<<endl; |
7fd59977 | 615 | #endif |
616 | } | |
617 | } | |
618 | } | |
619 | ||
620 | //======================================================================= | |
621 | //function : PerformElement | |
81bba717 | 622 | //purpose : find all mutually tangent edges ; |
623 | // Each edge has 2 opposing faces. For 2 adjacent tangent edges it is required that | |
624 | // the opposing faces were tangent. | |
7fd59977 | 625 | //======================================================================= |
626 | ||
627 | Standard_Boolean ChFi3d_Builder::PerformElement(const Handle(ChFiDS_Spine)& Spine) | |
628 | { | |
629 | Standard_Real ta = angular; | |
630 | TopTools_ListIteratorOfListOfShape It; | |
631 | Standard_Integer Nbface; | |
632 | TopTools_ListIteratorOfListOfShape Jt; | |
633 | Standard_Real Wl,Wf; | |
634 | Standard_Boolean degeneOnEc; | |
635 | gp_Pnt P2; | |
636 | gp_Vec V1,V2; | |
637 | TopoDS_Vertex Ve1,VStart,FVEc,LVEc,FVEv,LVEv; | |
638 | TopoDS_Edge Ev,Ec(Spine->Edges(1)); | |
639 | if(BRep_Tool::Degenerated(Ec)) return 0; | |
81bba717 | 640 | //it is checked if the edge is a cut edge |
7fd59977 | 641 | TopoDS_Face ff1,ff2; |
642 | ChFi3d_conexfaces(Ec,ff1,ff2,myEFMap); | |
643 | if(ff1.IsNull() || ff2.IsNull()) return 0; | |
644 | // Modified by Sergey KHROMOV - Fri Dec 21 17:46:22 2001 End | |
645 | //if(BRep_Tool::Continuity(Ec,ff1,ff2) != GeomAbs_C0) return 0; | |
646 | if (isTangentFaces(Ec,ff1,ff2)) return 0; | |
647 | // Modified by Sergey KHROMOV - Fri Dec 21 17:46:24 2001 Begin | |
648 | ||
649 | BRepAdaptor_Curve CEc,CEv; | |
650 | TopAbs_Orientation curor = Ec.Orientation(); | |
651 | TopExp::Vertices(Ec,VStart,LVEc); | |
652 | ||
653 | ||
654 | Standard_Boolean Fini = Standard_False; | |
655 | Standard_Integer Nb; | |
7fd59977 | 656 | ChFiDS_State CurSt = ChFiDS_Closed; |
81bba717 | 657 | if (VStart.IsSame(LVEc)) {//case if only one edge is closed |
7fd59977 | 658 | CEc.Initialize(Ec); |
659 | Wl = BRep_Tool::Parameter(VStart,Ec); | |
660 | CEc.D1(Wl,P2,V1); | |
661 | Wl = BRep_Tool::Parameter(LVEc,Ec); | |
662 | CEc.D1(Wl,P2,V2); | |
663 | if (V1.IsParallel(V2,ta)) { | |
664 | if (FaceTangency(Ec,Ec,VStart)) { | |
665 | CurSt = ChFiDS_Closed; | |
666 | } | |
667 | else { | |
668 | CurSt = ChFiDS_BreakPoint; | |
669 | } | |
670 | } | |
671 | else { | |
672 | CurSt = ChFiDS_BreakPoint; | |
673 | } | |
674 | Spine->SetLastStatus(CurSt); | |
675 | Spine->SetFirstStatus(CurSt); | |
676 | } | |
81bba717 | 677 | else { // Downstream progression |
7fd59977 | 678 | FVEc = VStart; |
679 | TopAbs_Orientation Or1; | |
680 | while (!Fini) { | |
681 | CurSt = ChFiDS_FreeBoundary; | |
682 | Wl = BRep_Tool::Parameter(LVEc,Ec); | |
683 | degeneOnEc = TangentOnVertex(LVEc, Ec, myEFMap, ta); | |
684 | CEc.Initialize(Ec); | |
685 | CEc.D1(Wl,P2,V1); | |
686 | Nb = Spine->NbEdges(); | |
687 | ||
688 | for (It.Initialize(myVEMap(LVEc));It.More();It.Next()) { | |
689 | Ev = TopoDS::Edge(It.Value()); | |
690 | if (!Ev.IsSame(Ec) && !BRep_Tool::Degenerated(Ev)){ | |
691 | TopExp::Vertices(Ev,FVEv,LVEv); | |
692 | if (LVEc.IsSame(LVEv)) { | |
693 | Ve1 = FVEv; | |
694 | FVEv = LVEv; | |
695 | LVEv = Ve1; | |
696 | Or1 = TopAbs_REVERSED; | |
697 | } | |
698 | else Or1 = TopAbs_FORWARD; | |
699 | ||
700 | Wf = BRep_Tool::Parameter(FVEv,Ev); | |
701 | CEv.Initialize(Ev); | |
702 | CEv.D1(Wf,P2,V2); | |
703 | Standard_Real av1v2 = V1.Angle(V2); | |
704 | Standard_Boolean rev = (Or1 != curor); | |
705 | Standard_Boolean OnAjoute = Standard_False; | |
706 | if (FaceTangency(Ec,Ev,FVEv)) { | |
81bba717 | 707 | // there is no need of tolerance |
708 | // to make a decision (PRO9486) the regularity is enough. | |
709 | // However, the abcense of turn-back is checked (PRO9810) | |
c6541a0c D |
710 | OnAjoute = ((!rev && av1v2 < M_PI/2) |
711 | ||(rev && av1v2 > M_PI/2)); | |
81bba717 | 712 | // mate attention to the single case (cf CTS21610_1) |
7fd59977 | 713 | if (OnAjoute && (degeneOnEc || |
714 | TangentOnVertex(LVEc, Ev,myEFMap, ta)) ) | |
c6541a0c | 715 | OnAjoute=((!rev && av1v2 < ta) || (rev && (M_PI - av1v2) < ta)); |
7fd59977 | 716 | } |
717 | if (OnAjoute) { | |
81bba717 | 718 | Fini = Standard_False; // If this can be useful (Cf PRO14713) |
7fd59977 | 719 | Ec = Ev; |
720 | // Ec = TopoDS::Edge(Ev); | |
721 | Ec.Orientation(Or1); | |
722 | Wl = Wf; LVEc = LVEv; | |
723 | Spine->SetEdges(Ec); | |
724 | curor = Or1; | |
725 | if (VStart.IsSame(LVEv)) { | |
726 | if (FaceTangency(Ev,Spine->Edges(1),LVEv)) { | |
727 | CurSt = ChFiDS_Closed; Fini = Standard_True; | |
728 | } | |
729 | else { | |
730 | CurSt = ChFiDS_BreakPoint;Fini = Standard_True; | |
731 | } | |
732 | } | |
733 | break; | |
734 | } | |
735 | else { | |
736 | for (Jt.Initialize(myEFMap(Ev)), Nbface= 0 ;Jt.More();Jt.Next(), | |
737 | Nbface++) {} | |
738 | if (Nbface> 1) CurSt = ChFiDS_BreakPoint; | |
c6541a0c | 739 | Fini = ((!rev && av1v2 < ta) || (rev && (M_PI - av1v2) < ta)); |
7fd59977 | 740 | } |
741 | } | |
742 | } | |
743 | Fini = Fini || (Nb == Spine->NbEdges()); | |
744 | } | |
745 | Spine->SetLastStatus(CurSt); | |
746 | if (CurSt == ChFiDS_Closed) { | |
747 | Spine->SetFirstStatus(CurSt); | |
748 | } | |
81bba717 | 749 | else {// Upstream progression |
7fd59977 | 750 | Fini = Standard_False; |
751 | Ec = Spine->Edges(1); | |
752 | curor = Ec.Orientation(); | |
753 | FVEc = VStart; | |
754 | while (!Fini) { | |
755 | CurSt = ChFiDS_FreeBoundary; | |
756 | Wl = BRep_Tool::Parameter(FVEc,Ec); | |
757 | degeneOnEc = TangentOnVertex(FVEc, Ec, myEFMap, ta); | |
758 | CEc.Initialize(Ec); | |
759 | CEc.D1(Wl,P2,V1); | |
760 | Nb = Spine->NbEdges(); | |
761 | ||
762 | for (It.Initialize(myVEMap(FVEc));It.More();It.Next()) { | |
763 | Ev = TopoDS::Edge(It.Value()); | |
764 | if (!Ev.IsSame(Ec) && !BRep_Tool::Degenerated(Ev)) { | |
765 | TopExp::Vertices(Ev,FVEv,LVEv); | |
766 | if (FVEc.IsSame(FVEv)) { | |
767 | Ve1 = FVEv; | |
768 | FVEv = LVEv; | |
769 | LVEv = Ve1; | |
770 | Or1 = TopAbs_REVERSED; | |
771 | } | |
772 | else { | |
773 | Or1 = TopAbs_FORWARD; | |
774 | } | |
775 | Wf = BRep_Tool::Parameter(LVEv,Ev); | |
776 | CEv.Initialize(Ev); | |
777 | CEv.D1(Wf,P2,V2); | |
778 | Standard_Real av1v2 = V1.Angle(V2); | |
779 | Standard_Boolean rev = (Or1 != curor); | |
780 | Standard_Boolean OnAjoute = Standard_False; | |
781 | if (FaceTangency(Ec,Ev,LVEv)) { | |
c6541a0c D |
782 | OnAjoute = ((!rev && av1v2 < M_PI/2) |
783 | ||(rev && av1v2 > M_PI/2)); | |
7fd59977 | 784 | if (OnAjoute && (degeneOnEc || |
785 | TangentOnVertex(FVEc, Ev,myEFMap, ta)) ) | |
c6541a0c | 786 | OnAjoute=((!rev && av1v2 < ta) || (rev && (M_PI-av1v2) < ta)); |
7fd59977 | 787 | } |
788 | if (OnAjoute) { | |
789 | Ec = Ev; | |
790 | // Ec = TopoDS::Edge(Ev); | |
791 | Ec.Orientation(Or1); | |
792 | Wl = Wf; FVEc = FVEv; | |
793 | Spine->PutInFirst(Ec); | |
794 | curor = Or1; | |
795 | break; | |
796 | } | |
797 | else { | |
798 | for(Jt.Initialize(myEFMap(Ev)),Nbface= 0 ;Jt.More();Jt.Next(), | |
799 | Nbface++) {} | |
800 | if (Nbface> 1) CurSt = ChFiDS_BreakPoint; | |
c6541a0c | 801 | Fini = ((!rev && av1v2 < ta) || (rev && (M_PI - av1v2) < ta)); |
7fd59977 | 802 | } |
803 | } | |
804 | } | |
805 | Fini = Fini || (Nb == Spine->NbEdges()); | |
806 | } | |
807 | Spine->SetFirstStatus(CurSt); | |
808 | } | |
809 | } | |
810 | return 1; | |
811 | } | |
812 | ||
813 | //======================================================================= | |
814 | //function : Remove | |
815 | //purpose : | |
816 | //======================================================================= | |
817 | ||
818 | void ChFi3d_Builder::Remove(const TopoDS_Edge& E) | |
819 | { | |
820 | ChFiDS_ListIteratorOfListOfStripe itel(myListStripe); | |
821 | ||
822 | for ( ; itel.More(); itel.Next()) { | |
823 | const Handle(ChFiDS_Spine)& sp = itel.Value()->Spine(); | |
824 | for (Standard_Integer j = 1; j <= sp->NbEdges(); j++){ | |
825 | if (E.IsSame(sp->Edges(j))){ | |
826 | myListStripe.Remove(itel); | |
827 | return; | |
828 | } | |
829 | } | |
830 | } | |
831 | } | |
832 | ||
833 | ||
834 | //======================================================================= | |
835 | //function : Value | |
836 | //purpose : | |
837 | //======================================================================= | |
838 | ||
839 | Handle(ChFiDS_Spine) ChFi3d_Builder::Value | |
840 | (const Standard_Integer I)const | |
841 | { | |
842 | ChFiDS_ListIteratorOfListOfStripe itel(myListStripe); | |
843 | for (Standard_Integer ic = 1; ic < I; ic++) {itel.Next();} | |
844 | return itel.Value()->Spine(); | |
845 | } | |
846 | ||
847 | //======================================================================= | |
848 | //function : NbElements | |
849 | //purpose : | |
850 | //======================================================================= | |
851 | ||
852 | Standard_Integer ChFi3d_Builder::NbElements()const | |
853 | { | |
854 | Standard_Integer i = 0; | |
855 | ChFiDS_ListIteratorOfListOfStripe itel(myListStripe); | |
856 | for ( ;itel.More(); itel.Next()){ | |
857 | const Handle(ChFiDS_Spine)& sp = itel.Value()->Spine(); | |
858 | if(sp.IsNull()) break; | |
859 | i++; | |
860 | } | |
861 | return i; | |
862 | } | |
863 | ||
864 | //======================================================================= | |
865 | //function : Contains | |
866 | //purpose : | |
867 | //======================================================================= | |
868 | ||
869 | Standard_Integer ChFi3d_Builder::Contains(const TopoDS_Edge& E)const | |
870 | { | |
871 | Standard_Integer i = 1,j; | |
872 | ChFiDS_ListIteratorOfListOfStripe itel(myListStripe); | |
873 | for ( ;itel.More(); itel.Next(), i++){ | |
874 | const Handle(ChFiDS_Spine)& sp = itel.Value()->Spine(); | |
875 | if(sp.IsNull()) break; | |
876 | for (j = 1; j <= sp->NbEdges(); j++){ | |
877 | if(E.IsSame(sp->Edges(j))) return i; | |
878 | } | |
879 | } | |
880 | return 0; | |
881 | } | |
882 | ||
883 | //======================================================================= | |
884 | //function : Contains | |
885 | //purpose : | |
886 | //======================================================================= | |
887 | ||
888 | Standard_Integer ChFi3d_Builder::Contains(const TopoDS_Edge& E, | |
889 | Standard_Integer& IndexInSpine)const | |
890 | { | |
891 | Standard_Integer i = 1,j; | |
892 | IndexInSpine = 0; | |
893 | ChFiDS_ListIteratorOfListOfStripe itel(myListStripe); | |
894 | for ( ;itel.More(); itel.Next(), i++){ | |
895 | const Handle(ChFiDS_Spine)& sp = itel.Value()->Spine(); | |
896 | if(sp.IsNull()) break; | |
897 | for (j = 1; j <= sp->NbEdges(); j++){ | |
898 | if(E.IsSame(sp->Edges(j))) | |
899 | { | |
900 | IndexInSpine = j; | |
901 | return i; | |
902 | } | |
903 | } | |
904 | } | |
905 | return 0; | |
906 | } | |
907 | ||
908 | //======================================================================= | |
909 | //function : Length | |
910 | //purpose : | |
911 | //======================================================================= | |
912 | ||
913 | Standard_Real ChFi3d_Builder::Length(const Standard_Integer IC)const | |
914 | { | |
915 | if(IC <= NbElements()){ | |
916 | const Handle(ChFiDS_Spine)& sp = Value(IC); | |
917 | return sp->LastParameter(sp->NbEdges()); | |
918 | } | |
919 | return -1; | |
920 | } | |
921 | ||
922 | ||
923 | //======================================================================= | |
924 | //function : FirstVertex | |
925 | //purpose : | |
926 | //======================================================================= | |
927 | ||
928 | TopoDS_Vertex ChFi3d_Builder::FirstVertex(const Standard_Integer IC) const | |
929 | { | |
930 | if(IC <= NbElements()){ | |
931 | return Value(IC)->FirstVertex(); | |
932 | } | |
933 | return TopoDS_Vertex(); | |
934 | } | |
935 | ||
936 | //======================================================================= | |
937 | //function : LastVertex | |
938 | //purpose : | |
939 | //======================================================================= | |
940 | ||
941 | TopoDS_Vertex ChFi3d_Builder::LastVertex(const Standard_Integer IC) const | |
942 | { | |
943 | if(IC <= NbElements()){ | |
944 | return Value(IC)->LastVertex(); | |
945 | } | |
946 | return TopoDS_Vertex(); | |
947 | } | |
948 | ||
949 | //======================================================================= | |
950 | //function : Abscissa | |
951 | //purpose : | |
952 | //======================================================================= | |
953 | ||
954 | Standard_Real ChFi3d_Builder::Abscissa(const Standard_Integer IC, | |
955 | const TopoDS_Vertex& V) const | |
956 | { | |
957 | if(IC <= NbElements()){ | |
958 | return Value(IC)->Absc(V); | |
959 | } | |
960 | return -1; | |
961 | } | |
962 | ||
963 | //======================================================================= | |
964 | //function : RelativeAbscissa | |
965 | //purpose : | |
966 | //======================================================================= | |
967 | ||
968 | Standard_Real ChFi3d_Builder::RelativeAbscissa(const Standard_Integer IC, | |
969 | const TopoDS_Vertex& V) const | |
970 | { | |
971 | if(IC <= NbElements()){ | |
972 | return Abscissa(IC,V)/Length(IC); | |
973 | } | |
974 | return -1; | |
975 | } | |
976 | ||
977 | //======================================================================= | |
978 | //function : Closed | |
979 | //purpose : | |
980 | //======================================================================= | |
981 | ||
982 | Standard_Boolean ChFi3d_Builder::Closed(const Standard_Integer IC)const | |
983 | { | |
984 | if(IC <= NbElements()){ | |
985 | return Value(IC)->IsClosed(); | |
986 | } | |
987 | return Standard_False; | |
988 | } | |
989 | ||
990 | //======================================================================= | |
991 | //function : ClosedAndTangent | |
992 | //purpose : | |
993 | //======================================================================= | |
994 | ||
995 | Standard_Boolean ChFi3d_Builder::ClosedAndTangent | |
996 | (const Standard_Integer IC)const | |
997 | { | |
998 | if(IC <= NbElements()){ | |
999 | return Value(IC)->IsPeriodic(); | |
1000 | } | |
1001 | return Standard_False; | |
1002 | } | |
1003 |