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