1 // Created on: 1993-12-15
2 // Created by: Isabelle GRIGNON
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
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>
30 #include <BRepAdaptor_Curve.hxx>
31 #include <BRepAdaptor_HCurve2d.hxx>
32 #include <BRepAdaptor_HSurface.hxx>
33 #include <BRepAdaptor_Surface.hxx>
34 #include <BRepBlend_Line.hxx>
35 #include <BRepLProp_SLProps.hxx>
36 #include <BRepTopAdaptor_TopolTool.hxx>
38 #include <ChFi3d_Builder.hxx>
39 #include <ChFi3d_Builder_0.hxx>
40 #include <ChFiDS_CommonPoint.hxx>
41 #include <ChFiDS_ErrorStatus.hxx>
42 #include <ChFiDS_FilSpine.hxx>
43 #include <ChFiDS_HData.hxx>
44 #include <ChFiDS_HElSpine.hxx>
45 #include <ChFiDS_ListIteratorOfListOfStripe.hxx>
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 <Geom_OffsetSurface.hxx>
55 #include <Geom_RectangularTrimmedSurface.hxx>
56 #include <GeomInt_IntSS.hxx>
57 #include <Extrema_ExtPC.hxx>
58 #include <GeomConvert_CompCurveToBSplineCurve.hxx>
59 #include <Geom_BSplineCurve.hxx>
61 #include <gp_Pnt2d.hxx>
63 #include <LocalAnalysis_SurfaceContinuity.hxx>
64 #include <Precision.hxx>
65 #include <Standard_ConstructionError.hxx>
66 #include <Standard_NoSuchObject.hxx>
67 #include <Standard_OutOfRange.hxx>
69 #include <TopAbs_Orientation.hxx>
70 #include <TopAbs_ShapeEnum.hxx>
73 #include <TopoDS_Edge.hxx>
74 #include <TopoDS_Face.hxx>
75 #include <TopoDS_Shape.hxx>
76 #include <TopoDS_Vertex.hxx>
77 #include <TopOpeBRepBuild_HBuilder.hxx>
78 #include <TopOpeBRepDS_HDataStructure.hxx>
79 #include <TopOpeBRepDS_Surface.hxx>
80 #include <TopOpeBRepTool_TOOL.hxx>
81 #include <TopTools_ListIteratorOfListOfShape.hxx>
82 #include <BRepLib_MakeEdge.hxx>
85 extern Standard_Boolean ChFi3d_GetcontextFORCEBLEND();
88 static void ReorderFaces(TopoDS_Face& theF1,
90 const TopoDS_Face& theFirstFace,
91 const TopoDS_Edge& thePrevEdge,
92 const TopoDS_Vertex& theCommonVertex)
94 if (theF1.IsSame(theFirstFace))
96 else if (theF2.IsSame(theFirstFace))
98 TopoDS_Face TmpFace = theF1; theF1 = theF2; theF2 = TmpFace;
102 TopTools_IndexedDataMapOfShapeListOfShape VEmapFirst, VEmap;
103 TopExp::MapShapesAndAncestors(theFirstFace, TopAbs_VERTEX, TopAbs_EDGE, VEmapFirst);
104 TopExp::MapShapesAndAncestors(theF1, TopAbs_VERTEX, TopAbs_EDGE, VEmap);
106 const TopTools_ListOfShape& ElistFirst = VEmapFirst.FindFromKey(theCommonVertex);
107 const TopTools_ListOfShape& Elist = VEmap.FindFromKey(theCommonVertex);
108 TopTools_ListIteratorOfListOfShape itlfirst(ElistFirst);
109 for (; itlfirst.More(); itlfirst.Next())
111 const TopoDS_Shape& anEdge = itlfirst.Value();
112 if (anEdge.IsSame(thePrevEdge))
114 TopTools_ListIteratorOfListOfShape itl(Elist);
115 for(; itl.More(); itl.Next())
116 if (anEdge.IsSame(itl.Value()))
120 TopoDS_Face TmpFace = theF1; theF1 = theF2; theF2 = TmpFace;
123 static void ConcatCurves(TColGeom_SequenceOfCurve& theCurves,
124 TColGeom_SequenceOfCurve& theNewCurves)
126 while (!theCurves.IsEmpty())
128 GeomConvert_CompCurveToBSplineCurve Concat;
129 Standard_Boolean Success = Standard_False;
130 for (Standard_Integer i = 1; i <= theCurves.Length(); i++)
132 const Handle(Geom_Curve)& aCurve = theCurves(i);
133 Handle(Geom_BoundedCurve) aBoundedCurve = Handle(Geom_BoundedCurve)::DownCast(aCurve);
134 Success = Concat.Add(aBoundedCurve, 1.e-5, Standard_True);
136 Success = Concat.Add(aBoundedCurve, 1.e-5, Standard_False);
143 Handle(Geom_Curve) aNewCurve = Concat.BSplineCurve();
144 theNewCurves.Append(aNewCurve);
148 static TopoDS_Edge MakeOffsetEdge(const TopoDS_Edge& theEdge,
149 const Standard_Real Distance,
150 const BRepAdaptor_Surface& S1,
151 const BRepAdaptor_Surface& S2)
153 TopoDS_Edge OffsetEdge;
155 TopoDS_Face F1 = S1.Face();
156 TopoDS_Face F2 = S2.Face();
157 Handle(Geom_Surface) GS1 = BRep_Tool::Surface(F1);
158 Handle(Geom_Surface) TrGS1 =
159 new Geom_RectangularTrimmedSurface(GS1,
160 S1.FirstUParameter(), S1.LastUParameter(),
161 S1.FirstVParameter(), S1.LastVParameter());
162 Standard_Real Offset = -Distance;
163 if (F1.Orientation() == TopAbs_REVERSED)
165 Handle(Geom_OffsetSurface) MakeOffsetSurf = new Geom_OffsetSurface(TrGS1, Offset);
166 Handle(Geom_Surface) OffsetTrGS1 = MakeOffsetSurf->Surface();
167 if (OffsetTrGS1.IsNull())
168 OffsetTrGS1 = MakeOffsetSurf;
169 Handle(Geom_Surface) GS2 = BRep_Tool::Surface(F2);
170 Handle(Geom_Surface) TrGS2 =
171 new Geom_RectangularTrimmedSurface(GS2,
172 S2.FirstUParameter(), S2.LastUParameter(),
173 S2.FirstVParameter(), S2.LastVParameter());
174 GeomInt_IntSS Intersector(OffsetTrGS1, TrGS2, Precision::Confusion());
175 if (!Intersector.IsDone() || Intersector.NbLines() == 0)
180 Handle(Geom_Curve) IntCurve = Intersector.Line(1);
182 BRepAdaptor_Curve aBAcurve(theEdge);
183 Ends[0] = aBAcurve.Value(aBAcurve.FirstParameter());
184 Ends[1] = aBAcurve.Value(aBAcurve.LastParameter());
186 if (Intersector.NbLines() > 1)
188 TColGeom_SequenceOfCurve Curves, NewCurves;
189 for (Standard_Integer i = 1; i <= Intersector.NbLines(); i++)
190 Curves.Append(Intersector.Line(i));
192 ConcatCurves(Curves, NewCurves);
194 Standard_Real MinDist = RealLast();
195 Standard_Integer imin = 1;
196 for (Standard_Integer i = 1; i <= NewCurves.Length(); i++)
198 GeomAdaptor_Curve GAcurve(NewCurves(i));
199 Extrema_ExtPC Projector(Ends[0], GAcurve);
200 if (!Projector.IsDone() || Projector.NbExt() == 0)
202 for (Standard_Integer iext = 1; iext <= Projector.NbExt(); iext++)
204 Standard_Real aDist = Projector.SquareDistance(iext);
212 IntCurve = NewCurves(imin);
214 if (IntCurve.IsNull())
218 //Projection of extremities onto <IntCurve>
219 GeomAdaptor_Curve GAcurve(IntCurve);
220 Standard_Real Params [2];
221 for (Standard_Integer ind_end = 0; ind_end < 2; ind_end++)
223 if (ind_end == 1 && aBAcurve.IsClosed()/*HGuide->IsPeriodic()*//*HGuide->IsClosed()*/)
225 Extrema_ExtPC Projector(Ends[ind_end], GAcurve);
226 Standard_Real param[4], dist[4];
228 param[1] = GAcurve.FirstParameter();
229 param[2] = GAcurve.LastParameter();
230 Projector.TrimmedSquareDistances(dist[1], dist[2], Pnt[1], Pnt[2]);
231 dist[3] = RealLast();
232 if (Projector.IsDone() && Projector.NbExt() > 0)
234 Standard_Integer imin = 1;
235 for (Standard_Integer i = 2; i <= Projector.NbExt(); i++)
236 if (Projector.SquareDistance(i) < Projector.SquareDistance(imin))
238 param[3] = Projector.Point(imin).Parameter();
239 dist[3] = Projector.SquareDistance(imin);
240 Pnt[3] = Projector.Point(imin).Value();
243 Standard_Integer imin = 1;
244 for (Standard_Integer i = 2; i <= 3; i++)
245 if (dist[i] < dist[imin])
248 Params[ind_end] = param[imin]; //Projector.Point(imin).Parameter();
250 if (aBAcurve.IsClosed()/*HGuide->IsPeriodic()*//*HGuide->IsClosed()*/)
251 Params[1] = GAcurve.LastParameter(); //temporary
252 if (Params[0] > Params[1])
254 Standard_Boolean IsClosed = Standard_False;
255 gp_Pnt fpnt = IntCurve->Value(IntCurve->FirstParameter());
256 gp_Pnt lpnt = IntCurve->Value(IntCurve->LastParameter());
257 if (fpnt.SquareDistance(lpnt) <= Precision::SquareConfusion())
258 IsClosed = Standard_True;
260 Params[1] = IntCurve->LastParameter();
263 Standard_Real NewFirstPar = IntCurve->ReversedParameter(Params[0]);
264 Standard_Real NewLastPar = IntCurve->ReversedParameter(Params[1]);
266 Params[0] = NewFirstPar;
267 Params[1] = NewLastPar;
270 if (aBAcurve.IsClosed()/*HGuide->IsPeriodic()*//*HGuide->IsClosed()*/) //check the direction of closed curve
272 gp_Pnt aPnt, anOffsetPnt;
273 gp_Vec Tangent, OffsetTangent;
274 aBAcurve.D1(aBAcurve.FirstParameter(), aPnt, Tangent);
275 IntCurve->D1(Params[0], anOffsetPnt, OffsetTangent);
276 if (Tangent*OffsetTangent < 0)
281 Standard_Real ParTol = 1.e-5;
282 Standard_Real FirstDiff = aBAcurve.FirstParameter() - Params[0];
283 Standard_Real LastDiff = aBAcurve.LastParameter() - Params[1];
284 if (Abs(FirstDiff) > ParTol ||
285 Abs(LastDiff) > ParTol)
287 Handle(Geom_BSplineCurve) BsplCurve = Handle(Geom_BSplineCurve)::DownCast(IntCurve);
288 TColStd_Array1OfReal aKnots(1, BsplCurve->NbKnots());
289 BsplCurve->Knots(aKnots);
290 BSplCLib::Reparametrize(aBAcurve.FirstParameter(), aBAcurve.LastParameter(), aKnots);
291 BsplCurve->SetKnots(aKnots);
292 if (aBAcurve.IsPeriodic() && !BsplCurve->IsPeriodic())
293 BsplCurve->SetPeriodic();
294 IntCurve = BsplCurve;
298 OffsetEdge = BRepLib_MakeEdge(IntCurve, Params[0], Params[1]);
302 static TopOpeBRepDS_BuildTool mkbuildtool()
304 TopOpeBRepTool_GeomTool GT2(TopOpeBRepTool_BSPLINE1,
308 TopOpeBRepDS_BuildTool BT(GT2);
309 BT.OverWrite(Standard_False);
310 BT.Translate(Standard_False);
314 //=======================================================================
315 //function : ChFi3d_Builder
317 //=======================================================================
318 ChFi3d_Builder::ChFi3d_Builder(const TopoDS_Shape& S,
319 const Standard_Real Ta) :
320 done(Standard_False), myShape(S)
322 myDS = new TopOpeBRepDS_HDataStructure();
323 myCoup = new TopOpeBRepBuild_HBuilder(mkbuildtool());
324 myEFMap.Fill(S,TopAbs_EDGE,TopAbs_FACE);
325 myESoMap.Fill(S,TopAbs_EDGE,TopAbs_SOLID);
326 myEShMap.Fill(S,TopAbs_EDGE,TopAbs_SHELL);
327 myVFMap.Fill(S,TopAbs_VERTEX,TopAbs_FACE);
328 myVEMap.Fill(S,TopAbs_VERTEX,TopAbs_EDGE);
329 SetParams(Ta,1.e-4,1.e-5,1.e-4,1.e-5,1.e-3);
330 SetContinuity(GeomAbs_C1, Ta);
333 //=======================================================================
334 //function : SetParams
336 //=======================================================================
338 void ChFi3d_Builder::SetParams(const Standard_Real Tang,
339 const Standard_Real Tesp,
340 const Standard_Real T2d,
341 const Standard_Real TApp3d,
342 const Standard_Real TolApp2d,
343 const Standard_Real Fleche)
353 //=======================================================================
354 //function : SetContinuity
356 //=======================================================================
358 void ChFi3d_Builder::SetContinuity(const GeomAbs_Shape InternalContinuity,
359 const Standard_Real AngularTolerance)
361 myConti = InternalContinuity;
362 tolappangle = AngularTolerance;
365 //=======================================================================
368 //=======================================================================
370 Standard_Boolean ChFi3d_Builder::IsDone() const
375 //=======================================================================
378 //=======================================================================
380 TopoDS_Shape ChFi3d_Builder::Shape()const
382 Standard_NoSuchObject_Raise_if (!done, "ChFi3d_Builder::Shape() - no result");
383 return myShapeResult;
386 //=======================================================================
387 //function : NbFaultyContours
389 //=======================================================================
391 Standard_Integer ChFi3d_Builder::NbFaultyContours() const
393 return badstripes.Extent();
396 //=======================================================================
397 //function : FaultyContour
399 //=======================================================================
401 Standard_Integer ChFi3d_Builder::FaultyContour(const Standard_Integer I) const
403 ChFiDS_ListIteratorOfListOfStripe itel;
404 Standard_Integer k = 0;
405 Handle(ChFiDS_Stripe) st;
406 for (itel.Initialize(badstripes);itel.More(); itel.Next()) {
413 if(st.IsNull()) return 0;
415 for (itel.Initialize(myListStripe);itel.More(); itel.Next()) {
417 if(st == itel.Value()) return k;
422 //=======================================================================
423 //function : NbComputedSurfaces
425 //=======================================================================
427 Standard_Integer ChFi3d_Builder::NbComputedSurfaces(const Standard_Integer IC) const
429 ChFiDS_ListIteratorOfListOfStripe itel;
430 Standard_Integer k = 0;
431 Handle(ChFiDS_Stripe) st;
432 for (itel.Initialize(myListStripe);itel.More(); itel.Next()) {
439 if(st.IsNull()) return 0;
440 if(st->Spine().IsNull()) return 0;
441 Handle(ChFiDS_HData) hd = st->SetOfSurfData();
442 if(hd.IsNull()) return 0;
446 //=======================================================================
447 //function : ComputedSurface
449 //=======================================================================
451 Handle(Geom_Surface) ChFi3d_Builder::ComputedSurface(const Standard_Integer IC,
452 const Standard_Integer IS) const
454 ChFiDS_ListIteratorOfListOfStripe itel;
455 Standard_Integer k = 0;
456 Handle(ChFiDS_Stripe) st;
457 for (itel.Initialize(myListStripe);itel.More(); itel.Next()) {
464 Handle(ChFiDS_HData) hd = st->SetOfSurfData();
465 Standard_Integer isurf=hd->Value(IS)->Surf();
466 return myDS->Surface(isurf).Surface();
469 //=======================================================================
470 //function : NbFaultyVertices
472 //=======================================================================
474 Standard_Integer ChFi3d_Builder::NbFaultyVertices() const
476 return badvertices.Extent();
479 //=======================================================================
480 //function : FaultyVertex
482 //=======================================================================
484 TopoDS_Vertex ChFi3d_Builder::FaultyVertex(const Standard_Integer IV) const
486 TopTools_ListIteratorOfListOfShape it;
488 Standard_Integer k = 0;
489 for(it.Initialize(badvertices);it.More(); it.Next()) {
492 V = TopoDS::Vertex(it.Value());
499 //=======================================================================
500 //function : HasResult
502 //=======================================================================
504 Standard_Boolean ChFi3d_Builder::HasResult() const
509 //=======================================================================
510 //function : BadShape
512 //=======================================================================
514 TopoDS_Shape ChFi3d_Builder::BadShape()const
516 Standard_NoSuchObject_Raise_if (!hasresult, "ChFi3d_Builder::BadShape() - no result");
520 //=======================================================================
521 //function : StripeStatus
523 //=======================================================================
525 ChFiDS_ErrorStatus ChFi3d_Builder::StripeStatus(const Standard_Integer IC)const
527 ChFiDS_ListIteratorOfListOfStripe itel;
528 Standard_Integer k =0;
529 Handle(ChFiDS_Stripe) st;
530 for (itel.Initialize(myListStripe);itel.More(); itel.Next()) {
537 ChFiDS_ErrorStatus stat=st->Spine()->ErrorStatus();
541 //=======================================================================
544 //=======================================================================
546 Handle(TopOpeBRepBuild_HBuilder) ChFi3d_Builder::Builder()const
551 //=======================================================================
552 //function : ChFi3d_FaceTangency
553 //purpose : determine if the faces opposing to edges are tangent
554 // to go from opposing faces on e0 to opposing faces
555 // on e1, consider all faces starting at a common top.
556 //=======================================================================
558 Standard_Boolean ChFi3d_Builder::FaceTangency(const TopoDS_Edge& E0,
559 const TopoDS_Edge& E1,
560 const TopoDS_Vertex& V) const
562 TopTools_ListIteratorOfListOfShape It,Jt;
564 Standard_Integer Nbf;
567 //It is checked if the connection is not on a regular edge.
568 for (It.Initialize(myEFMap(E1)), Nbf= 0 ;It.More();It.Next(), Nbf++) {
570 throw Standard_ConstructionError("ChFi3d_Builder:only 2 faces");
571 F[Nbf] = TopoDS::Face(It.Value());
573 if(Nbf < 2) return Standard_False;
574 // Modified by Sergey KHROMOV - Fri Dec 21 17:44:19 2001 Begin
575 //if (BRep_Tool::Continuity(E1,F[0],F[1]) != GeomAbs_C0) {
576 if (ChFi3d_isTangentFaces(E1,F[0],F[1])) {
577 // Modified by Sergey KHROMOV - Fri Dec 21 17:44:21 2001 End
578 return Standard_False;
581 for (Jt.Initialize(myVEMap(V));Jt.More();Jt.Next()) {
582 Ec = TopoDS::Edge(Jt.Value());
583 if (!Ec.IsSame(E0) && !Ec.IsSame(E1) &&
584 Ec.Orientation() != TopAbs_INTERNAL &&
585 Ec.Orientation() != TopAbs_EXTERNAL &&
586 !BRep_Tool::Degenerated(Ec)) {
587 for (It.Initialize(myEFMap(Ec)), Nbf= 0 ;It.More();It.Next(), Nbf++) {
589 throw Standard_ConstructionError("ChFi3d_Builder:only 2 faces");
590 F[Nbf] = TopoDS::Face(It.Value());
592 if(Nbf < 2) return Standard_False;
593 // Modified by Sergey KHROMOV - Tue Dec 18 18:10:40 2001 Begin
594 // if (BRep_Tool::Continuity(Ec,F[0],F[1]) < GeomAbs_G1) {
595 if (!ChFi3d_isTangentFaces(Ec,F[0],F[1])) {
596 // Modified by Sergey KHROMOV - Tue Dec 18 18:10:41 2001 End
597 return Standard_False;
601 return Standard_True;
606 //=======================================================================
607 //function : TangentExtremity
608 //purpose : Test if 2 faces are tangent at the end of an edge
609 //=======================================================================
610 static Standard_Boolean TangentExtremity(const TopoDS_Vertex& V,
611 const TopoDS_Edge& E,
612 const Handle(BRepAdaptor_HSurface)& hs1,
613 const Handle(BRepAdaptor_HSurface)& hs2,
614 // const Standard_Real t3d,
615 const Standard_Real tang)
617 TopoDS_Face f1 = hs1->ChangeSurface().Face();
618 TopAbs_Orientation O1 = f1.Orientation();
619 f1.Orientation(TopAbs_FORWARD);
620 TopoDS_Face f2 = hs2->ChangeSurface().Face();
621 TopAbs_Orientation O2 = f2.Orientation();
622 f2.Orientation(TopAbs_FORWARD);
623 TopoDS_Edge e1 = E, e2 = E;
624 e1.Orientation(TopAbs_FORWARD);
625 e2.Orientation(TopAbs_FORWARD);
626 if(f1.IsSame(f2) && BRep_Tool::IsClosed(e1,f1))
627 e2.Orientation(TopAbs_REVERSED);
628 Standard_Real p1 = BRep_Tool::Parameter(V,e1,f1);
629 Standard_Real p2 = BRep_Tool::Parameter(V,e2,f2);
630 Standard_Real u,v,f,l, Eps = 1.e-9;
631 gp_Vec n1, n2;// gp_Pnt pt1,pt2;
632 Handle(Geom2d_Curve) pc1 = BRep_Tool::CurveOnSurface(e1,f1,f,l);
633 pc1->Value(p1).Coord(u,v);
634 BRepLProp_SLProps theProp1(hs1->ChangeSurface(), u, v, 1, Eps);
635 if (theProp1.IsNormalDefined()) {
636 n1.SetXYZ(theProp1.Normal().XYZ());
637 if (O1 == TopAbs_REVERSED) n1.Reverse();
639 else return Standard_False; // It is not known...
642 Handle(Geom2d_Curve) pc2 = BRep_Tool::CurveOnSurface(e2,f2,f,l);
643 pc2->Value(p2).Coord(u,v);
644 BRepLProp_SLProps theProp2(hs2->ChangeSurface(), u, v, 1, Eps);
645 if (theProp2.IsNormalDefined()) {
646 n2.SetXYZ(theProp2.Normal().XYZ());
647 if(O2 == TopAbs_REVERSED) n2.Reverse();
649 else return Standard_False; // It is not known...
651 return (n1.Angle(n2) < tang);
654 //=======================================================================
655 //function : TangentOnVertex
656 //purpose : Test if support faces of an edge are tangent at end.
657 //=======================================================================
658 static Standard_Boolean TangentOnVertex(const TopoDS_Vertex& V,
659 const TopoDS_Edge& E,
660 const ChFiDS_Map& EFMap,
661 const Standard_Real tang)
664 ChFi3d_conexfaces(E,ff1,ff2,EFMap);
665 if(ff1.IsNull() || ff2.IsNull()) return 0;
666 Handle(BRepAdaptor_HSurface) S1 = new (BRepAdaptor_HSurface)(ff1);
667 Handle(BRepAdaptor_HSurface) S2 = new (BRepAdaptor_HSurface)(ff2);
668 return TangentExtremity(V, E, S1, S2, tang);
671 //=======================================================================
672 //function : PerformExtremity
673 //purpose : In case if PerformElement returned BreakPoint at one or
674 // another extremity, it is attempted to refine
675 // depending on concavities between neighbour faces of the top.
676 //=======================================================================
678 void ChFi3d_Builder::PerformExtremity (const Handle(ChFiDS_Spine)& Spine)
680 Standard_Integer NbG1Connections = 0;
682 for(Standard_Integer ii = 1; ii <= 2; ii++){
686 Standard_Integer iedge;
687 Handle(BRepAdaptor_HSurface) hs1,hs2;
689 sst = Spine->FirstStatus();
691 V = Spine->FirstVertex();
694 sst = Spine->LastStatus();
695 iedge = Spine->NbEdges();
696 E[0] = Spine->Edges(iedge);
697 V = Spine->LastVertex();
699 //Before all it is checked if the tangency is not dead.
700 E[0] = Spine->Edges(iedge);
701 ConexFaces (Spine,iedge,hs1,hs2);
702 if(TangentExtremity(V,E[0],hs1,hs2,angular)){
703 Spine->SetTangencyExtremity(Standard_True, (ii == 1));
706 if(sst == ChFiDS_BreakPoint){
707 TopTools_ListIteratorOfListOfShape It;//,Jt;
708 Standard_Integer i = 0;
709 Standard_Boolean sommetpourri = Standard_False;
710 TopTools_IndexedMapOfShape EdgesOfV;
711 //to avoid repeating of edges
712 for (It.Initialize(myVEMap(V)); It.More(); It.Next())
713 EdgesOfV.Add(It.Value());
714 for (Standard_Integer ind = 1; ind <= EdgesOfV.Extent(); ind++) {
715 Ec = TopoDS::Edge(EdgesOfV(ind));
716 Standard_Boolean bonedge = !BRep_Tool::Degenerated(Ec);
720 ChFi3d_conexfaces(Ec, F1, F2, myEFMap);
721 if (!F2.IsNull() && ChFi3d_isTangentFaces(Ec, F1, F2, GeomAbs_G2))
723 bonedge = Standard_False;
729 if (!Ec.IsSame(E[0]))
737 std::cout<<"top has more than 3 edges"<<std::endl;
739 sommetpourri = Standard_True;
745 if(i != 2) sommetpourri = Standard_True;
747 sst = ChFi3d_EdgeState(E,myEFMap);
749 if(ii==1)Spine->SetFirstStatus(sst);
750 else Spine->SetLastStatus(sst);
754 if (!Spine->IsPeriodic()) {
755 TopTools_ListIteratorOfListOfShape It,Jt;
756 Standard_Integer nbf = 0, jf = 0;
757 for (It.Initialize(myVFMap(Spine->FirstVertex())); It.More(); It.Next()){
759 Standard_Integer kf = 1;
760 const TopoDS_Shape& cur = It.Value();
761 for (Jt.Initialize(myVFMap(Spine->FirstVertex())); Jt.More() && (kf < jf); Jt.Next(), kf++){
762 if(cur.IsSame(Jt.Value())) break;
766 nbf -= NbG1Connections;
768 Spine->SetFirstStatus(ChFiDS_BreakPoint);
770 std::cout<<"top has : "<<nbf<<" faces."<<std::endl;
774 for (It.Initialize(myVFMap(Spine->LastVertex())); It.More(); It.Next()){
776 Standard_Integer kf = 1;
777 const TopoDS_Shape& cur = It.Value();
778 for (Jt.Initialize(myVFMap(Spine->LastVertex())); Jt.More() && (kf < jf); Jt.Next(), kf++){
779 if(cur.IsSame(Jt.Value())) break;
783 nbf -= NbG1Connections;
785 Spine->SetLastStatus(ChFiDS_BreakPoint);
787 std::cout<<"top has : "<<nbf<<" faces."<<std::endl;
793 //=======================================================================
794 //function : PerformElement
795 //purpose : find all mutually tangent edges ;
796 // Each edge has 2 opposing faces. For 2 adjacent tangent edges it is required that
797 // the opposing faces were tangent.
798 //=======================================================================
800 Standard_Boolean ChFi3d_Builder::PerformElement(const Handle(ChFiDS_Spine)& Spine,
801 const Standard_Real Offset,
802 const TopoDS_Face& theFirstFace)
804 Standard_Real ta = angular;
805 TopTools_ListIteratorOfListOfShape It;
806 Standard_Integer Nbface;
807 TopTools_ListIteratorOfListOfShape Jt;
809 Standard_Boolean degeneOnEc;
812 TopoDS_Vertex Ve1,VStart,FVEc,LVEc,FVEv,LVEv;
813 TopoDS_Edge Ev,Ec(Spine->Edges(1));
814 if(BRep_Tool::Degenerated(Ec)) return 0;
815 //it is checked if the edge is a cut edge
817 ChFi3d_conexfaces(Ec,ff1,ff2,myEFMap);
818 if(ff1.IsNull() || ff2.IsNull()) return 0;
819 // Modified by Sergey KHROMOV - Fri Dec 21 17:46:22 2001 End
820 //if(BRep_Tool::Continuity(Ec,ff1,ff2) != GeomAbs_C0) return 0;
821 if (ChFi3d_isTangentFaces(Ec,ff1,ff2)) return 0;
822 // Modified by Sergey KHROMOV - Fri Dec 21 17:46:24 2001 Begin
824 TopoDS_Face FirstFace = ff1;
825 if (!theFirstFace.IsNull() && ff2.IsSame(theFirstFace))
828 ff2 = ff1; ff1 = FirstFace;
830 myEdgeFirstFace.Bind(Ec, FirstFace);
831 Standard_Boolean ToRestrict = (Offset > 0)? Standard_True : Standard_False;
832 BRepAdaptor_Surface Sb1(ff1, ToRestrict);
833 BRepAdaptor_Surface Sb2(ff2, ToRestrict);
836 TopoDS_Edge OffsetEdge = MakeOffsetEdge(Ec, Offset, Sb1, Sb2);
837 OffsetEdge.Orientation(Ec.Orientation());
838 Spine->SetOffsetEdges(OffsetEdge);
841 BRepAdaptor_Curve CEc,CEv;
842 TopAbs_Orientation curor = Ec.Orientation();
843 TopExp::Vertices(Ec,VStart,LVEc);
846 Standard_Boolean Fini = Standard_False;
848 ChFiDS_State CurSt = ChFiDS_Closed;
849 if (VStart.IsSame(LVEc)) {//case if only one edge is closed
851 Wl = BRep_Tool::Parameter(VStart,Ec);
853 Wl = BRep_Tool::Parameter(LVEc,Ec);
855 if (V1.IsParallel(V2,ta)) {
856 if (FaceTangency(Ec,Ec,VStart)) {
857 CurSt = ChFiDS_Closed;
860 CurSt = ChFiDS_BreakPoint;
864 CurSt = ChFiDS_BreakPoint;
866 Spine->SetLastStatus(CurSt);
867 Spine->SetFirstStatus(CurSt);
869 else { // Downstream progression
871 TopAbs_Orientation Or1;
873 CurSt = ChFiDS_FreeBoundary;
874 Wl = BRep_Tool::Parameter(LVEc,Ec);
875 degeneOnEc = TangentOnVertex(LVEc, Ec, myEFMap, ta);
878 Nb = Spine->NbEdges();
880 for (It.Initialize(myVEMap(LVEc));It.More();It.Next()) {
881 Ev = TopoDS::Edge(It.Value());
882 if (!Ev.IsSame(Ec) && !BRep_Tool::Degenerated(Ev)){
883 TopExp::Vertices(Ev,FVEv,LVEv);
884 if (LVEc.IsSame(LVEv)) {
888 Or1 = TopAbs_REVERSED;
890 else Or1 = TopAbs_FORWARD;
892 Wf = BRep_Tool::Parameter(FVEv,Ev);
895 Standard_Real av1v2 = V1.Angle(V2);
896 Standard_Boolean rev = (Or1 != curor);
897 Standard_Boolean OnAjoute = Standard_False;
898 if (FaceTangency(Ec,Ev,FVEv)) {
899 // there is no need of tolerance
900 // to make a decision (PRO9486) the regularity is enough.
901 // However, the abcense of turn-back is checked (PRO9810)
902 OnAjoute = ((!rev && av1v2 < M_PI/2)
903 ||(rev && av1v2 > M_PI/2));
904 // mate attention to the single case (cf CTS21610_1)
905 if (OnAjoute && (degeneOnEc ||
906 TangentOnVertex(LVEc, Ev,myEFMap, ta)) )
907 OnAjoute=((!rev && av1v2 < ta) || (rev && (M_PI - av1v2) < ta));
910 Fini = Standard_False; // If this can be useful (Cf PRO14713)
911 TopoDS_Vertex CommonVertex;
912 TopExp::CommonVertex(Ec, Ev, CommonVertex);
913 TopoDS_Edge PrevEdge = Ec;
915 // Ec = TopoDS::Edge(Ev);
917 Wl = Wf; LVEc = LVEv;
919 TopoDS_Face CurF1, CurF2;
920 ChFi3d_conexfaces(Ec,CurF1,CurF2,myEFMap);
921 ReorderFaces(CurF1, CurF2, FirstFace, PrevEdge, CommonVertex);
922 myEdgeFirstFace.Bind(Ec, CurF1);
925 BRepAdaptor_Surface CurSb1(CurF1), CurSb2(CurF2);
926 TopoDS_Edge anOffsetEdge = MakeOffsetEdge(Ec, Offset, CurSb1, CurSb2);
927 anOffsetEdge.Orientation(Or1);
928 Spine->SetOffsetEdges(anOffsetEdge);
932 if (VStart.IsSame(LVEv)) {
933 if (FaceTangency(Ev,Spine->Edges(1),LVEv)) {
934 CurSt = ChFiDS_Closed; Fini = Standard_True;
937 CurSt = ChFiDS_BreakPoint;Fini = Standard_True;
943 for (Jt.Initialize(myEFMap(Ev)), Nbface= 0 ;Jt.More();Jt.Next(),
945 if (Nbface> 1) CurSt = ChFiDS_BreakPoint;
946 Fini = ((!rev && av1v2 < ta) || (rev && (M_PI - av1v2) < ta));
950 Fini = Fini || (Nb == Spine->NbEdges());
952 Spine->SetLastStatus(CurSt);
953 if (CurSt == ChFiDS_Closed) {
954 Spine->SetFirstStatus(CurSt);
956 else {// Upstream progression
957 Fini = Standard_False;
958 Ec = Spine->Edges(1);
959 FirstFace = TopoDS::Face(myEdgeFirstFace(Ec));
960 curor = Ec.Orientation();
963 CurSt = ChFiDS_FreeBoundary;
964 Wl = BRep_Tool::Parameter(FVEc,Ec);
965 degeneOnEc = TangentOnVertex(FVEc, Ec, myEFMap, ta);
968 Nb = Spine->NbEdges();
970 for (It.Initialize(myVEMap(FVEc));It.More();It.Next()) {
971 Ev = TopoDS::Edge(It.Value());
972 if (!Ev.IsSame(Ec) && !BRep_Tool::Degenerated(Ev)) {
973 TopExp::Vertices(Ev,FVEv,LVEv);
974 if (FVEc.IsSame(FVEv)) {
978 Or1 = TopAbs_REVERSED;
981 Or1 = TopAbs_FORWARD;
983 Wf = BRep_Tool::Parameter(LVEv,Ev);
986 Standard_Real av1v2 = V1.Angle(V2);
987 Standard_Boolean rev = (Or1 != curor);
988 Standard_Boolean OnAjoute = Standard_False;
989 if (FaceTangency(Ec,Ev,LVEv)) {
990 OnAjoute = ((!rev && av1v2 < M_PI/2)
991 ||(rev && av1v2 > M_PI/2));
992 if (OnAjoute && (degeneOnEc ||
993 TangentOnVertex(FVEc, Ev,myEFMap, ta)) )
994 OnAjoute=((!rev && av1v2 < ta) || (rev && (M_PI-av1v2) < ta));
997 TopoDS_Vertex CommonVertex;
998 TopExp::CommonVertex(Ec, Ev, CommonVertex);
999 TopoDS_Edge PrevEdge = Ec;
1001 // Ec = TopoDS::Edge(Ev);
1002 Ec.Orientation(Or1);
1003 Wl = Wf; FVEc = FVEv;
1004 Spine->PutInFirst(Ec);
1005 TopoDS_Face CurF1, CurF2;
1006 ChFi3d_conexfaces(Ec,CurF1,CurF2,myEFMap);
1007 ReorderFaces(CurF1, CurF2, FirstFace, PrevEdge, CommonVertex);
1008 myEdgeFirstFace.Bind(Ec, CurF1);
1011 BRepAdaptor_Surface CurSb1(CurF1), CurSb2(CurF2);
1012 TopoDS_Edge anOffsetEdge = MakeOffsetEdge(Ec, Offset, CurSb1, CurSb2);
1013 anOffsetEdge.Orientation(Or1);
1014 Spine->PutInFirstOffset(anOffsetEdge);
1021 for(Jt.Initialize(myEFMap(Ev)),Nbface= 0 ;Jt.More();Jt.Next(),
1023 if (Nbface> 1) CurSt = ChFiDS_BreakPoint;
1024 Fini = ((!rev && av1v2 < ta) || (rev && (M_PI - av1v2) < ta));
1028 Fini = Fini || (Nb == Spine->NbEdges());
1030 Spine->SetFirstStatus(CurSt);
1036 //=======================================================================
1039 //=======================================================================
1041 void ChFi3d_Builder::Remove(const TopoDS_Edge& E)
1043 ChFiDS_ListIteratorOfListOfStripe itel(myListStripe);
1045 for ( ; itel.More(); itel.Next()) {
1046 const Handle(ChFiDS_Spine)& sp = itel.Value()->Spine();
1047 for (Standard_Integer j = 1; j <= sp->NbEdges(); j++){
1048 if (E.IsSame(sp->Edges(j))){
1049 myListStripe.Remove(itel);
1057 //=======================================================================
1060 //=======================================================================
1062 Handle(ChFiDS_Spine) ChFi3d_Builder::Value
1063 (const Standard_Integer I)const
1065 ChFiDS_ListIteratorOfListOfStripe itel(myListStripe);
1066 for (Standard_Integer ic = 1; ic < I; ic++) {itel.Next();}
1067 return itel.Value()->Spine();
1070 //=======================================================================
1071 //function : NbElements
1073 //=======================================================================
1075 Standard_Integer ChFi3d_Builder::NbElements()const
1077 Standard_Integer i = 0;
1078 ChFiDS_ListIteratorOfListOfStripe itel(myListStripe);
1079 for ( ;itel.More(); itel.Next()){
1080 const Handle(ChFiDS_Spine)& sp = itel.Value()->Spine();
1081 if(sp.IsNull()) break;
1087 //=======================================================================
1088 //function : Contains
1090 //=======================================================================
1092 Standard_Integer ChFi3d_Builder::Contains(const TopoDS_Edge& E)const
1094 Standard_Integer i = 1,j;
1095 ChFiDS_ListIteratorOfListOfStripe itel(myListStripe);
1096 for ( ;itel.More(); itel.Next(), i++){
1097 const Handle(ChFiDS_Spine)& sp = itel.Value()->Spine();
1098 if(sp.IsNull()) break;
1099 for (j = 1; j <= sp->NbEdges(); j++){
1100 if(E.IsSame(sp->Edges(j))) return i;
1106 //=======================================================================
1107 //function : Contains
1109 //=======================================================================
1111 Standard_Integer ChFi3d_Builder::Contains(const TopoDS_Edge& E,
1112 Standard_Integer& IndexInSpine)const
1114 Standard_Integer i = 1,j;
1116 ChFiDS_ListIteratorOfListOfStripe itel(myListStripe);
1117 for ( ;itel.More(); itel.Next(), i++){
1118 const Handle(ChFiDS_Spine)& sp = itel.Value()->Spine();
1119 if(sp.IsNull()) break;
1120 for (j = 1; j <= sp->NbEdges(); j++){
1121 if(E.IsSame(sp->Edges(j)))
1131 //=======================================================================
1134 //=======================================================================
1136 Standard_Real ChFi3d_Builder::Length(const Standard_Integer IC)const
1138 if(IC <= NbElements()){
1139 const Handle(ChFiDS_Spine)& sp = Value(IC);
1140 return sp->LastParameter(sp->NbEdges());
1146 //=======================================================================
1147 //function : FirstVertex
1149 //=======================================================================
1151 TopoDS_Vertex ChFi3d_Builder::FirstVertex(const Standard_Integer IC) const
1153 if(IC <= NbElements()){
1154 return Value(IC)->FirstVertex();
1156 return TopoDS_Vertex();
1159 //=======================================================================
1160 //function : LastVertex
1162 //=======================================================================
1164 TopoDS_Vertex ChFi3d_Builder::LastVertex(const Standard_Integer IC) const
1166 if(IC <= NbElements()){
1167 return Value(IC)->LastVertex();
1169 return TopoDS_Vertex();
1172 //=======================================================================
1173 //function : Abscissa
1175 //=======================================================================
1177 Standard_Real ChFi3d_Builder::Abscissa(const Standard_Integer IC,
1178 const TopoDS_Vertex& V) const
1180 if(IC <= NbElements()){
1181 return Value(IC)->Absc(V);
1186 //=======================================================================
1187 //function : RelativeAbscissa
1189 //=======================================================================
1191 Standard_Real ChFi3d_Builder::RelativeAbscissa(const Standard_Integer IC,
1192 const TopoDS_Vertex& V) const
1194 if(IC <= NbElements()){
1195 return Abscissa(IC,V)/Length(IC);
1200 //=======================================================================
1203 //=======================================================================
1205 Standard_Boolean ChFi3d_Builder::Closed(const Standard_Integer IC)const
1207 if(IC <= NbElements()){
1208 return Value(IC)->IsClosed();
1210 return Standard_False;
1213 //=======================================================================
1214 //function : ClosedAndTangent
1216 //=======================================================================
1218 Standard_Boolean ChFi3d_Builder::ClosedAndTangent
1219 (const Standard_Integer IC)const
1221 if(IC <= NbElements()){
1222 return Value(IC)->IsPeriodic();
1224 return Standard_False;