1 // Created on: 1994-12-02
2 // Created by: Jacques GOUSSARD
3 // Copyright (c) 1994-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
22 #include <Draft_Modification.jxx>
24 #include <BRep_Tool.hxx>
25 #include <BRep_Builder.hxx>
27 #include <BRepLib_MakeFace.hxx>
29 #include <TopLoc_Location.hxx>
30 #include <TopExp_Explorer.hxx>
31 #include <TopTools_ListIteratorOfListOfShape.hxx>
33 #include <Draft_DataMapIteratorOfDataMapOfFaceFaceInfo.hxx>
34 #include <Draft_DataMapIteratorOfDataMapOfEdgeEdgeInfo.hxx>
35 #include <Draft_DataMapIteratorOfDataMapOfVertexVertexInfo.hxx>
36 #include <Draft_FaceInfo.hxx>
37 #include <Draft_EdgeInfo.hxx>
38 #include <Draft_VertexInfo.hxx>
39 #include <BRep_Tool.hxx>
40 #include <BRep_Tool.hxx>
42 #include <Geom_Surface.hxx>
43 #include <Geom_RectangularTrimmedSurface.hxx>
46 #include <Geom2d_Line.hxx>
47 #include <Geom_Plane.hxx>
48 #include <Geom_SurfaceOfLinearExtrusion.hxx>
49 #include <Geom_CylindricalSurface.hxx>
50 #include <Geom_ConicalSurface.hxx>
51 #include <Geom_Curve.hxx>
52 #include <Geom_Line.hxx>
53 #include <Geom_Circle.hxx>
54 #include <Geom_Ellipse.hxx>
55 #include <Geom_Parabola.hxx>
56 #include <Geom_Hyperbola.hxx>
57 #include <Geom_TrimmedCurve.hxx>
58 #include <GeomAdaptor_Curve.hxx>
59 #include <GeomAdaptor_Surface.hxx>
60 #include <Adaptor3d_SurfaceOfLinearExtrusion.hxx>
65 #include <gp_Circ.hxx>
66 #include <gp_Elips.hxx>
67 #include <gp_Parab.hxx>
68 #include <gp_Hypr.hxx>
70 #include <IntCurveSurface_HInter.hxx>
71 #include <GeomInt_IntSS.hxx>
72 #include <IntCurveSurface_IntersectionPoint.hxx>
73 #include <IntAna_QuadQuadGeo.hxx>
74 #include <IntAna_IntConicQuad.hxx>
76 #include <Extrema_ExtPC.hxx>
77 #include <BRepExtrema_ExtPC.hxx>
78 #include <BRepExtrema_ExtCF.hxx>
80 #include <Standard_DomainError.hxx>
81 #include <Standard_Failure.hxx>
82 #include <Standard_NotImplemented.hxx>
84 #include <TopTools_MapOfShape.hxx>
85 #include <TopTools_MapIteratorOfMapOfShape.hxx>
88 #include <Precision.hxx>
91 #include <BRepTools.hxx>
95 #include <GeomAdaptor_HCurve.hxx>
96 #include <GeomAdaptor_HSurface.hxx>
97 #include <GeomAPI_ProjectPointOnSurf.hxx>
99 #include <GeomAPI_ProjectPointOnCurve.hxx>
101 #include <Geom2d_TrimmedCurve.hxx>
102 #include <Geom2dAPI_ProjectPointOnCurve.hxx>
103 #include <Geom2d_BSplineCurve.hxx>
104 #include <Geom2dConvert.hxx>
105 #include <Geom2dAdaptor_HCurve.hxx>
106 #include <Adaptor3d_CurveOnSurface.hxx>
108 #include <GeomProjLib.hxx>
109 #include <TColgp_Array1OfPnt2d.hxx>
110 #include <Geom2d_BezierCurve.hxx>
111 #include <Geom2dConvert_CompCurveToBSplineCurve.hxx>
113 #include <Adaptor3d_HCurveOnSurface.hxx>
114 #include <ProjLib_CompProjectedCurve.hxx>
115 #include <ProjLib_HCompProjectedCurve.hxx>
116 #include <Approx_CurveOnSurface.hxx>
118 #include <GeomConvert_CompCurveToBSplineCurve.hxx>
121 static Standard_Boolean Choose(const Draft_DataMapOfFaceFaceInfo&,
122 Draft_DataMapOfEdgeEdgeInfo&,
123 const TopoDS_Vertex&,
126 GeomAdaptor_Surface&);
128 static Standard_Real Parameter(const Handle(Geom_Curve)&,
132 static Standard_Real SmartParameter(Draft_EdgeInfo&,
133 const Standard_Real EdgeTol,
135 const Standard_Integer,
136 const Handle(Geom_Surface)&,
137 const Handle(Geom_Surface)&);
139 static TopAbs_Orientation Orientation(const TopoDS_Shape&,
142 static Standard_Boolean FindRotation(const gp_Pln&,
143 const TopAbs_Orientation,
151 //=======================================================================
152 //function : InternalAdd
154 //=======================================================================
156 Standard_Boolean Draft_Modification::InternalAdd(const TopoDS_Face& F,
157 const gp_Dir& Direction,
158 const Standard_Real Angle,
159 const gp_Pln& NeutralPlane,
160 const Standard_Boolean Flag)
163 if (myFMap.IsBound(F)) {
164 return (badShape.IsNull());
167 TopAbs_Orientation oris = Orientation(myShape,F);
169 //gp_Dir NewDirection = Direction;
170 //Standard_Real NewAngle = Angle;
171 Handle(Geom_Surface) S = BRep_Tool::Surface(F,Lo);
172 S = Handle(Geom_Surface)::DownCast(S->Transformed(Lo.Transformation()));
173 if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
174 S = Handle(Geom_RectangularTrimmedSurface)::DownCast(S)->BasisSurface();
176 Handle(Geom_Surface) NewS;
177 Handle(Geom_Circle) theCircle;
179 Standard_Boolean postponed = (Flag == Standard_False);
181 Handle(Standard_Type) typS = S->DynamicType();
182 if (typS == STANDARD_TYPE(Geom_CylindricalSurface) ||
183 typS == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
185 if (typS == STANDARD_TYPE(Geom_CylindricalSurface)) {
187 Handle(Geom_CylindricalSurface)::DownCast(S)->Cylinder();
188 gp_Ax1 axcyl = cyl.Axis();
189 Cir = ElSLib::CylinderVIso( cyl.Position(), cyl.Radius(), 0.);
190 gp_Vec VV(cyl.Location(),NeutralPlane.Location());
191 Cir.Translate(VV.Dot(axcyl.Direction())*axcyl.Direction());
194 Handle(Geom_Curve) Cbas =
195 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(S)->BasisCurve();
197 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(S)->Direction();
199 if (Cbas->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
200 Cbas = Handle(Geom_TrimmedCurve)::DownCast(Cbas)->BasisCurve();
202 if (Cbas->IsKind(STANDARD_TYPE(Geom_Circle))) {
203 Cir = Handle(Geom_Circle)::DownCast(Cbas)->Circ();
204 gp_Dir dircir = Cir.Axis().Direction();
205 if (!Direction.IsParallel(dircir,Precision::Angular())) {
207 errStat = Draft_FaceRecomputation;
208 return Standard_False;
213 errStat = Draft_FaceRecomputation;
214 return Standard_False;
217 gp_Ax3 Axis = NeutralPlane.Position();
219 gp_Vec(Cir.Location(),Axis.Location()).
220 Dot(Axis.Direction());
221 Standard_Real Cos = theDirextr.Dot(Axis.Direction());
222 gp_Vec VV = ( L / Cos) * theDirextr;
226 theCircle = new Geom_Circle(Cir);
230 postponed = Standard_False;
236 NewS = NewSurface(S,oris,Direction,Angle,NeutralPlane);
239 errStat = Draft_FaceRecomputation;
240 return Standard_False;
242 // To avoid some problems with infinite restrictions
243 const Handle(Standard_Type)& typs = NewS->DynamicType();
244 if (typs == STANDARD_TYPE(Geom_CylindricalSurface) ||
245 typs == STANDARD_TYPE(Geom_ConicalSurface)) {
246 Standard_Real umin,umax,vmin,vmax;
247 BRepTools::UVBounds(F,umin,umax,vmin,vmax);
248 if (!Precision::IsNegativeInfinite(vmin) &&
249 !Precision::IsPositiveInfinite(vmax)) {
250 Standard_Real deltav = 10.*(vmax-vmin);
251 if(typs == STANDARD_TYPE(Geom_CylindricalSurface)) {
252 vmin = vmin - deltav;
253 vmax = vmax + deltav;
256 gp_Cone Co = Handle(Geom_ConicalSurface)::DownCast(NewS)->Cone();
257 Standard_Real Vapex = - Co.RefRadius()/Sin(Co.SemiAngle());
258 if (vmin < Vapex) { // vmax should not exceed Vapex
259 if (vmax + deltav > Vapex) {
261 vmin = vmin - 10.*(vmax - vmin);
262 // JAG debug to avoid apex
263 vmax = vmax-Precision::Confusion();
266 vmin = vmin - deltav;
267 vmax = vmax + deltav;
270 else { // Vapex <= vmin < vmax
271 if (vmin - deltav < Vapex) {
273 vmax = vmax + 10.*(vmax - vmin);
274 // JAG debug to avoid apex
275 vmin = vmin+Precision::Confusion();
278 vmin = vmin - deltav;
279 vmax = vmax + deltav;
283 NewS = new Geom_RectangularTrimmedSurface(NewS,0.,2.*M_PI,vmin,vmax);
288 if (postponed || S != NewS) {
289 Draft_FaceInfo FI(NewS,Standard_True);
290 FI.RootFace(curFace);
293 myFMap(F).ChangeCurve() = theCircle;
297 TopExp_Explorer expl(F,TopAbs_EDGE);
298 TopTools_MapOfShape MapOfE;
299 while (expl.More() && badShape.IsNull()) {
300 const TopoDS_Edge& edg = TopoDS::Edge(expl.Current());
301 if (!myEMap.IsBound(edg)) {
302 Standard_Boolean addedg = Standard_False;
303 Standard_Boolean addface = Standard_False;
305 // if (BRep_Tool::IsClosed(edg,F)) {
306 if (BRepTools::IsReallyClosed(edg,F)) {
307 addedg = Standard_True;
308 addface = Standard_False;
311 // Find the other face containing the edge.
312 TopTools_ListIteratorOfListOfShape it;
313 it.Initialize(myEFMap.FindFromKey(edg));
314 Standard_Integer nbother = 0;
316 if (!it.Value().IsSame(F)) {
317 if (OtherF.IsNull()) {
318 OtherF = TopoDS::Face(it.Value());
326 errStat = Draft_EdgeRecomputation;
328 else if (! OtherF.IsNull() &&
329 BRep_Tool::Continuity(edg,F,OtherF) >= GeomAbs_G1) {
330 addface= Standard_True;
331 addedg = Standard_True;
333 else if (nbother == 0) {
339 myFMap(F).Add(OtherF);
343 Handle(Geom_Curve) C = BRep_Tool::Curve(edg,L,f,l);
344 C = Handle(Geom_Curve)::DownCast(C->Transformed(L));
345 if (C->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) {
346 C = Handle(Geom_TrimmedCurve)::DownCast(C)->BasisCurve();
348 Handle(Geom_Curve) NewC;
349 Draft_EdgeInfo EInf(Standard_True);
355 Handle(Geom_Line) aLocalGeom = Handle(Geom_Line)::DownCast(C);
356 if (aLocalGeom.IsNull()) {
358 errStat = Draft_EdgeRecomputation;
361 gp_Lin lin = aLocalGeom->Lin();
362 IntAna_IntConicQuad ilipl(lin,NeutralPlane,Precision::Angular());
363 if (ilipl.IsDone() && ilipl.NbPoints() != 0){
364 EInf.Tangent(ilipl.Point(1));
368 errStat = Draft_EdgeRecomputation;
373 NewC = NewCurve(C,S,oris,Direction,Angle,NeutralPlane, Flag);
376 errStat = Draft_EdgeRecomputation;
380 Handle(Geom_TrimmedCurve) T = Handle(Geom_TrimmedCurve)::DownCast(NewC);
381 if (!T.IsNull()) NewC = T->BasisCurve();
382 EInf.ChangeGeometry() = NewC;
384 EInf.RootFace(curFace);
385 myEMap.Bind(edg,EInf);
388 Standard_Boolean Fl = Flag;
389 Handle(Geom_Surface) alocalSurface = BRep_Tool::Surface(OtherF,Lo);
390 if (alocalSurface->DynamicType() ==
391 STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
392 alocalSurface = Handle(Geom_RectangularTrimmedSurface)::
393 DownCast(alocalSurface)->BasisSurface();
395 Handle(Standard_Type) typS = alocalSurface->DynamicType();
396 if (typS == STANDARD_TYPE(Geom_CylindricalSurface) ||
397 typS == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
398 if ( myFMap.IsBound(F)) {
399 if ( Flag == Standard_False && !postponed) {
401 TopTools_MapIteratorOfMapOfShape itm(MapOfE);
402 for ( ; itm.More(); itm.Next())
403 myEMap.UnBind(TopoDS::Edge(itm.Key()));
407 InternalAdd(OtherF,Direction,Angle,NeutralPlane, Fl);
413 return (badShape.IsNull());
417 //=======================================================================
418 //function : Propagate
420 //=======================================================================
422 Standard_Boolean Draft_Modification::Propagate ()
425 if (!badShape.IsNull()) return Standard_False;
427 Draft_DataMapIteratorOfDataMapOfFaceFaceInfo itf(myFMap);
429 // Set all edges and vertices of modified faces
433 TopExp_Explorer editer;
434 TopExp_Explorer vtiter;
437 const TopoDS_Face& Fc = itf.Key();
439 // Exploration of the edges of the face
440 editer.Init(Fc,TopAbs_EDGE);
441 while (editer.More()) {
442 E = TopoDS::Edge(editer.Current());
444 if (!myEMap.IsBound(E)) {
445 Draft_EdgeInfo EInf(Standard_True);
450 // Exploration of the vertices of the edge
451 vtiter.Init(E,TopAbs_VERTEX);
452 while (vtiter.More()) {
453 V = TopoDS::Vertex(vtiter.Current());
454 if (!myVMap.IsBound(V)) {
455 Draft_VertexInfo VInf;
460 myVMap(V).ChangeParameter(E) = BRep_Tool::Parameter(V, E);
470 Standard_Boolean found;
472 // Set edges containing modified vertices.
474 Draft_DataMapIteratorOfDataMapOfVertexVertexInfo itv(myVMap);
477 const TopoDS_Vertex& Vt = itv.Key();
479 // Exploration of the ancestors of the vertex
480 anc.Init(myShape,TopAbs_EDGE);
483 E = TopoDS::Edge(anc.Current());
484 vtiter.Init(E,TopAbs_VERTEX);
485 found = Standard_False;
486 while (vtiter.More()) {
487 if (Vt.IsSame(TopoDS::Vertex(vtiter.Current()))) {
488 found = Standard_True;
494 if (!myEMap.IsBound(E)) {
495 Draft_EdgeInfo EInf(Standard_False);
499 myVMap(Vt).ChangeParameter(E) = BRep_Tool::Parameter(Vt, E);
507 // Set faces containing modified edges
509 Draft_DataMapIteratorOfDataMapOfEdgeEdgeInfo ite(myEMap);
512 const TopoDS_Edge& Ed = ite.Key();
513 TopTools_ListIteratorOfListOfShape it;
514 for (it.Initialize(myEFMap.FindFromKey(Ed)); it.More(); it.Next()) {
515 F = TopoDS::Face(it.Value());
516 if (!myFMap.IsBound(F)) {
518 Handle(Geom_Surface) S = BRep_Tool::Surface(F,L);
519 Handle(Geom_Surface) NewS =
520 Handle(Geom_Surface)::DownCast(S->Transformed(L.Transformation()));
522 const Handle(Standard_Type)& typs = S->DynamicType();
523 if (typs == STANDARD_TYPE(Geom_CylindricalSurface) ||
524 typs == STANDARD_TYPE(Geom_ConicalSurface)) {
525 Standard_Real umin,umax,vmin,vmax;
526 BRepTools::UVBounds(F,umin,umax,vmin,vmax);
527 if (!Precision::IsNegativeInfinite(vmin) &&
528 !Precision::IsPositiveInfinite(vmax)) {
529 Standard_Real deltav = 10.*(vmax-vmin);
530 vmin = vmin - deltav;
531 vmax = vmax + deltav;
533 new Geom_RectangularTrimmedSurface(NewS,0.,2.*M_PI,vmin,vmax);
537 Draft_FaceInfo FInf(NewS,Standard_False);
545 // Try to add faces for free borders...
547 ite.Initialize(myEMap);
548 for (; ite.More(); ite.Next()) {
549 Draft_EdgeInfo& Einf = myEMap(ite.Key());
550 if (Einf.NewGeometry() && Einf.Geometry().IsNull() &&
551 Einf.SecondFace().IsNull()) {
554 Handle(Geom_Surface) S1 = BRep_Tool::Surface(Einf.FirstFace(),Loc);
555 S1 = Handle(Geom_Surface)::
556 DownCast(S1->Transformed(Loc.Transformation()));
557 Handle(Geom_Surface) S2;
560 Handle(Geom_Curve) C = BRep_Tool::Curve(ite.Key(),Loc,f,l);
561 C = Handle(Geom_Curve)::DownCast(C->Transformed(Loc.Transformation()));
562 if (C->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) {
563 C = Handle(Geom_TrimmedCurve)::DownCast(C)->BasisCurve();
565 if (!S1->IsKind(STANDARD_TYPE(Geom_Plane))) {
566 if (C->IsKind(STANDARD_TYPE(Geom_Conic))) {
567 gp_Ax3 thePl(Handle(Geom_Conic)::DownCast(C)->Position());
568 S2 = new Geom_Plane(thePl);
570 else if (C->DynamicType() == STANDARD_TYPE(Geom_Line)) {
572 if (S1->DynamicType()== STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
573 axis = Handle(Geom_ElementarySurface)::DownCast
574 (Handle(Geom_RectangularTrimmedSurface)::DownCast(S1)->
575 BasisSurface())->Axis();
578 axis = Handle(Geom_ElementarySurface)::DownCast(S1)->Axis();
580 gp_Vec they(axis.Location(), C->Value(0.));
581 gp_Dir axz(axis.Direction().Crossed(they));
582 S2=new Geom_Plane(gp_Ax3(axis.Location(),axz,axis.Direction()));
586 badShape = TopoDS::Edge(ite.Key());
587 errStat = Draft_EdgeRecomputation;
588 break; // leave from for
591 else { // on the plane
592 Draft_DataMapIteratorOfDataMapOfVertexVertexInfo anewitv(myVMap);
593 while (anewitv.More()) {
594 Draft_VertexInfo& Vinf = myVMap(anewitv.Key());
595 for (Vinf.InitEdgeIterator();Vinf.MoreEdge();Vinf.NextEdge()) {
596 if (Vinf.Edge().IsSame(ite.Key())) {
600 if (Vinf.MoreEdge()) {
601 for (Vinf.InitEdgeIterator();Vinf.MoreEdge();Vinf.NextEdge()) {
602 const TopoDS_Edge& edg = Vinf.Edge();
603 if (!edg.IsSame(ite.Key())) {
604 if (!myEMap(edg).FirstFace().IsSame(Einf.FirstFace()) &&
605 (myEMap(edg).SecondFace().IsNull() ||
606 !myEMap(edg).SecondFace().IsSame(Einf.FirstFace()))) {
611 if (Vinf.MoreEdge()) {
612 Handle(Geom_Curve) C2 = BRep_Tool::Curve(Vinf.Edge(), Loc,f,l);
613 Handle(GeomAdaptor_HCurve) HCur;
615 C2 = Handle(Geom_Curve)::DownCast
616 (C2->Transformed(Loc.Transformation()));
617 if (C2->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) {
618 C2 = Handle(Geom_TrimmedCurve)::DownCast(C2)->BasisCurve();
620 if (C->DynamicType() == STANDARD_TYPE(Geom_Line)) {
621 Direc = Handle(Geom_Line)::DownCast(C)->Lin().Direction();
622 HCur = new GeomAdaptor_HCurve(C2);
625 else if (C2->DynamicType() == STANDARD_TYPE(Geom_Line)) {
626 Direc = Handle(Geom_Line)::DownCast(C2)->Lin().Direction();
627 HCur = new GeomAdaptor_HCurve(C);
630 badShape = TopoDS::Edge(ite.Key());
631 errStat = Draft_EdgeRecomputation;
632 break; // leave from while
634 Adaptor3d_SurfaceOfLinearExtrusion SLE(HCur,Direc);
635 switch(SLE.GetType()){
639 S2 = new Geom_Plane(SLE.Plane());
642 case GeomAbs_Cylinder :
644 S2 = new Geom_CylindricalSurface(SLE.Cylinder());
649 S2 = new Geom_SurfaceOfLinearExtrusion(HCur->ChangeCurve().
658 badShape = TopoDS::Edge(ite.Key());
659 errStat = Draft_EdgeRecomputation;
660 break; // leave from while
668 if (badShape.IsNull()) {
670 TopoDS_Face TheNewFace;
671 B.MakeFace(TheNewFace,S2,Precision::Confusion());
672 Einf.Add(TheNewFace);
673 Draft_FaceInfo FI(S2,Standard_False);
674 myFMap.Bind(TheNewFace,FI);
677 break; // leave from for
682 return (badShape.IsNull());
688 //=======================================================================
691 //=======================================================================
693 void Draft_Modification::Perform ()
695 if (!badShape.IsNull()) Standard_ConstructionError::Raise();
698 myComp = Standard_True;
703 // Calculate eventual faces
705 Draft_DataMapIteratorOfDataMapOfFaceFaceInfo itf(myFMap);
707 Draft_FaceInfo& Finf = myFMap(itf.Key());
708 if (Finf.NewGeometry() && Finf.Geometry().IsNull()) {
709 const TopoDS_Face& F1 = Finf.FirstFace();
710 const TopoDS_Face& F2 = Finf.SecondFace();
712 if (F1.IsNull() || F2.IsNull()) {
713 errStat = Draft_FaceRecomputation;
714 badShape = TopoDS::Face(itf.Key());
717 Handle(Geom_Surface) S1 = myFMap(F1).Geometry();
718 Handle(Geom_Surface) S2 = myFMap(F2).Geometry();
719 if (S1.IsNull() || S2.IsNull()) {
720 errStat = Draft_FaceRecomputation;
721 badShape = TopoDS::Face(itf.Key());
724 if (S1->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
725 S1 = Handle(Geom_RectangularTrimmedSurface)::
726 DownCast(S1)->BasisSurface();
728 if (S2->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
729 S2 = Handle(Geom_RectangularTrimmedSurface)::
730 DownCast(S2)->BasisSurface();
732 Handle(Geom_Plane) P1 = Handle(Geom_Plane)::DownCast(S1);
733 Handle(Geom_Plane) P2 = Handle(Geom_Plane)::DownCast(S2);
734 if (P1.IsNull() || P2.IsNull()) {
735 errStat = Draft_FaceRecomputation;
736 badShape = TopoDS::Face(itf.Key());
739 gp_Pln pp1 = P1->Pln();
740 gp_Pln pp2 = P2->Pln();
741 IntAna_QuadQuadGeo i2p(pp1,pp2,
742 Precision::Angular(),Precision::Confusion());
743 if (!i2p.IsDone() || i2p.TypeInter() != IntAna_Line) {
744 errStat = Draft_FaceRecomputation;
745 badShape = TopoDS::Face(itf.Key());
749 gp_Dir extrdir = i2p.Line(1).Direction();
751 // Preserve the same direction as the base face
752 Handle(Geom_Surface) RefSurf =
753 BRep_Tool::Surface(TopoDS::Face(itf.Key()));
754 if (RefSurf->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
756 Handle(Geom_RectangularTrimmedSurface)::DownCast(RefSurf)
761 if ( RefSurf->DynamicType() == STANDARD_TYPE(Geom_CylindricalSurface)) {
763 Handle(Geom_CylindricalSurface)::DownCast(RefSurf)
764 ->Cylinder().Position();
765 DirRef = AxeRef.Direction();
767 else if (RefSurf->DynamicType() ==
768 STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
770 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(RefSurf)
774 if (extrdir.Dot(DirRef) < 0.) extrdir.Reverse();
776 // it is possible to accelerate speed by storing the info during
777 // InternalAdd --> modification of FaceInfo to preserve the circle
779 Handle(Geom_Circle) CCir =
780 Handle(Geom_Circle)::DownCast(Finf.Curve());
781 Handle(Geom_Surface) NewS =
782 new Geom_SurfaceOfLinearExtrusion(CCir, extrdir);
784 Standard_Real umin, umax, vmin, vmax;
785 BRepTools::UVBounds(TopoDS::Face(itf.Key()),umin,umax,vmin,vmax);
786 if (!Precision::IsNegativeInfinite(vmin) &&
787 !Precision::IsPositiveInfinite(vmax)) {
788 Standard_Real deltav = 2.*(vmax-vmin);
789 vmin = vmin - deltav;
790 vmax = vmax + deltav;
799 NewS = new Geom_RectangularTrimmedSurface(NewS,0.,1.9*M_PI,vmin,vmax);
800 Finf.ChangeGeometry() = NewS;
805 // Calculate new edges.
807 Handle(Geom_Surface) S1,S2;
808 Handle(Geom_Curve) C, newC;
811 Draft_DataMapIteratorOfDataMapOfEdgeEdgeInfo ite(myEMap);
814 Draft_EdgeInfo& Einf = myEMap(ite.Key());
816 const TopoDS_Edge& theEdge = TopoDS::Edge(ite.Key());
818 C = BRep_Tool::Curve(theEdge,L,f,l);
819 C = Handle(Geom_Curve)::DownCast(C->Transformed(L.Transformation()));
821 if (Einf.NewGeometry() && Einf.Geometry().IsNull()) {
823 if (!Einf.IsTangent(ptfixe)) {
824 const TopoDS_Face& FirstFace = Einf.FirstFace();
825 const TopoDS_Face& SecondFace = Einf.SecondFace();
827 S1 = myFMap(FirstFace).Geometry();
828 S2 = myFMap(SecondFace).Geometry();
830 Standard_Integer detrompeur = 0;
832 // Return FirstVertex and the tangent at this point.
833 TopoDS_Vertex FV = TopExp::FirstVertex(theEdge);
834 TopoDS_Vertex LV = TopExp::LastVertex(theEdge);
835 Standard_Real pmin = 0.;
836 Standard_Real prmfv = BRep_Tool::Parameter(FV,ite.Key());
837 Standard_Real prmlv = BRep_Tool::Parameter(LV,ite.Key());
839 gp_Vec d1fv,d1lv, newd1;
840 C->D1(prmfv,pfv,d1fv);
841 C->D1(prmlv,plv,d1lv);
843 Standard_Real TolF1 = BRep_Tool::Tolerance (FirstFace);
844 Standard_Real TolF2 = BRep_Tool::Tolerance (SecondFace);
846 //Pass the tolerance of the face to project
847 GeomAPI_ProjectPointOnSurf proj1 (pfv, S1, TolF1);
848 GeomAPI_ProjectPointOnSurf proj2 (plv, S1, TolF1);
849 GeomAPI_ProjectPointOnSurf proj3 (pfv, S2, TolF2);
850 GeomAPI_ProjectPointOnSurf proj4 (plv, S2, TolF2);
852 if (proj1.IsDone () && proj2.IsDone ()) {
853 if(proj1.LowerDistance()<= Precision::Confusion() &&
854 proj2.LowerDistance()<= Precision::Confusion()) {
859 if (proj3.IsDone () && proj4.IsDone ()) {
860 if(proj3.LowerDistance() <= Precision::Confusion() &&
861 proj4.LowerDistance() <= Precision::Confusion()) {
868 Handle(Geom_Curve) TheNewCurve;
869 Standard_Boolean KPart = Standard_False;
871 if ( S1->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
872 S1 = Handle(Geom_RectangularTrimmedSurface)::
873 DownCast(S1)->BasisSurface();
875 if ( S2->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
876 S2 = Handle(Geom_RectangularTrimmedSurface)::
877 DownCast(S2)->BasisSurface();
880 Standard_Boolean PC1 = Standard_True; // KPart on S1
881 if (S1->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion) &&
882 S2->DynamicType() == STANDARD_TYPE(Geom_Plane) ) {
883 KPart = Standard_True;
884 Axis = Handle(Geom_Plane)::DownCast(S2)->Position();
885 TheNewCurve = Handle(Geom_SurfaceOfLinearExtrusion)::
886 DownCast(S1)->BasisCurve();
887 TheDirExtr = Handle(Geom_SurfaceOfLinearExtrusion)::
888 DownCast(S1)->Direction();
890 else if (S2->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion) &&
891 S1->DynamicType() == STANDARD_TYPE(Geom_Plane) ) {
892 KPart = Standard_True;
893 PC1 = Standard_False;
894 Axis = Handle(Geom_Plane)::DownCast(S1)->Position();
895 TheNewCurve = Handle(Geom_SurfaceOfLinearExtrusion)::
896 DownCast(S2)->BasisCurve();
897 TheDirExtr = Handle(Geom_SurfaceOfLinearExtrusion)::
898 DownCast(S2)->Direction();
900 Handle(Geom_Circle) aCirc ;
901 if ( KPart) { // very temporary on circles !!!
902 aCirc = Handle(Geom_Circle)::DownCast(TheNewCurve);
904 KPart = Standard_False;
907 gp_Dir AxofCirc = aCirc->Position().Direction();
908 if (AxofCirc.IsParallel(Axis.Direction(),Precision::Angular()))
909 KPart = Standard_True;
911 KPart = Standard_False;
915 Standard_Integer imin;
918 // direct calculation of NewC
919 Standard_Real aLocalReal =
920 gp_Vec(aCirc->Circ().Location(),Axis.Location()).
921 Dot(Axis.Direction());
922 Standard_Real Cos = TheDirExtr.Dot(Axis.Direction());
923 gp_Vec VV = ( aLocalReal / Cos) * TheDirExtr;
924 newC = Handle(Geom_Curve)::DownCast(TheNewCurve->Translated(VV));
925 // it is possible to calculate PCurve
926 Handle(Geom2d_Line) L2d
927 = new Geom2d_Line(gp_Pnt2d(0.,aLocalReal/Cos),
931 Einf.ChangeFirstPC() = L2d;
933 Einf.ChangeSecondPC() = L2d;
936 S1 = myFMap(Einf.FirstFace()).Geometry();
937 S2 = myFMap(Einf.SecondFace()).Geometry();
940 // PCurves are not calculated immediately for 2 reasons:
941 // 1 - If ProjLib should make an Approx, it is stupid to approximate the
942 // entire intersection curve.
943 // 2 - Additionally, if YaRev, there is a risk to not be SameRange.
944 i2s.Perform(S1,S2,Precision::Confusion(),
945 Standard_True,Standard_False,Standard_False);
947 if (!i2s.IsDone() || i2s.NbLines() <= 0) {
948 errStat = Draft_EdgeRecomputation;
949 badShape = TopoDS::Edge(ite.Key());
953 Standard_Real Dist2, Dist2Min = 0., Glob2Min = RealLast();
954 GeomAdaptor_Curve TheCurve;
956 Standard_Integer i,j; //,jmin;
958 if (i2s.Line(1)->DynamicType() != STANDARD_TYPE(Geom_BSplineCurve))
961 for (i=1; i<= i2s.NbLines(); i++) {
962 TheCurve.Load(i2s.Line(i));
963 Extrema_ExtPC myExtPC(pfv,TheCurve);
965 Standard_Real locpmin = 0.;
966 if (myExtPC.IsDone()) {
967 if(myExtPC.NbExt() >= 1) {
968 Dist2Min = myExtPC.SquareDistance(1);
969 locpmin = myExtPC.Point(1).Parameter();
971 if(myExtPC.NbExt() == 2 && Dist2Min > Precision::SquareConfusion()) {
972 //to avoid incorrectly choosing the image
973 //of the first vertex of the initial edge
974 Standard_Real d1_2 = myExtPC.SquareDistance(1);
975 Standard_Real d2_2 = myExtPC.SquareDistance(2);
976 if(d1_2 > 1.21*d2_2) {
977 Dist2Min = myExtPC.SquareDistance(2);
978 locpmin = myExtPC.Point(2).Parameter();
980 else if(d2_2 > 1.21*d1_2) {
981 Dist2Min = myExtPC.SquareDistance(1);
982 locpmin = myExtPC.Point(1).Parameter();
985 Standard_Real pfvpar = myExtPC.Point(1).Parameter();
986 Standard_Real plvpar = myExtPC.Point(2).Parameter();
989 gp_Pnt pfvprim, plvprim;
991 newC->D0(pfvpar,pfvprim);
992 newC->D0(plvpar,plvprim);
994 Handle(Geom_Surface) theSurf;
995 if(detrompeur == 1) {
996 if(S1->DynamicType() ==
997 STANDARD_TYPE(Geom_RectangularTrimmedSurface))
998 S1 = Handle(Geom_RectangularTrimmedSurface)::
999 DownCast(S1)->BasisSurface();
1003 else if(detrompeur == 2) {
1004 if(S2->DynamicType() ==
1005 STANDARD_TYPE(Geom_RectangularTrimmedSurface))
1006 S2 = Handle(Geom_RectangularTrimmedSurface)::
1007 DownCast(S2)->BasisSurface();
1010 if(detrompeur != 0 && detrompeur != 4) {
1011 Standard_Real ul = 0., vl = 0., uf = 0., vf = 0.;
1012 Standard_Real ufprim = 0., ulprim = 0., vfprim = 0., vlprim = 0.;
1014 if(theSurf->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
1015 gp_Pln pl = Handle(Geom_Plane)::DownCast(S2)->Pln();
1016 ElSLib::Parameters(pl, plv, ul, vl);
1017 ElSLib::Parameters(pl, pfv, uf, vf);
1018 ElSLib::Parameters(pl, plvprim, ulprim, vlprim);
1019 ElSLib::Parameters(pl, pfvprim, ufprim, vfprim);
1021 else if(theSurf->DynamicType() ==
1022 STANDARD_TYPE(Geom_CylindricalSurface)) {
1023 gp_Cylinder cy = Handle(Geom_CylindricalSurface)
1024 ::DownCast(S2)->Cylinder();
1025 ElSLib::Parameters(cy, plv, ul, vl);
1026 ElSLib::Parameters(cy, pfv, uf, vf);
1027 ElSLib::Parameters(cy, plvprim, ulprim, vlprim);
1028 ElSLib::Parameters(cy, pfvprim, ufprim, vfprim);
1030 else detrompeur = 4;
1032 if(detrompeur == 1 || detrompeur == 2) {
1033 gp_Vec2d v1((ul-ufprim), (vl-vfprim));
1034 gp_Vec2d norm((vf-vfprim), (ufprim-uf));
1035 gp_Vec2d v2((ulprim-ufprim), (vlprim-vfprim));
1036 if( (v1.Dot(norm))*(v2.Dot(norm)) < 0) {
1037 Dist2Min = myExtPC.SquareDistance(2);
1038 locpmin = myExtPC.Point(2).Parameter();
1044 if (myExtPC.NbExt() == 1 || myExtPC.NbExt() > 2 || detrompeur ==4) {
1045 Dist2Min = myExtPC.SquareDistance(1);
1046 locpmin = myExtPC.Point(1).Parameter();
1047 for (j=2; j<=myExtPC.NbExt(); j++) {
1048 Dist2 = myExtPC.SquareDistance(j);
1049 if (Dist2 < Dist2Min) {
1051 locpmin = myExtPC.Point(j).Parameter();
1055 else if(myExtPC.NbExt() < 1){
1056 Standard_Real dist1_2,dist2_2;
1058 myExtPC.TrimmedSquareDistances(dist1_2,dist2_2,p1b,p2b);
1059 if (dist1_2 < dist2_2) {
1061 locpmin = TheCurve.FirstParameter();
1065 locpmin = TheCurve.LastParameter();
1069 if (Dist2Min < Glob2Min) {
1070 Glob2Min = Dist2Min;
1077 errStat = Draft_EdgeRecomputation;
1078 badShape = TopoDS::Edge(ite.Key());
1082 newC = i2s.Line(imin);
1084 newC->D1(pmin,pfv,newd1);
1085 Standard_Boolean YaRev = d1fv.Dot(newd1) <0.;
1090 if (i2s.HasLineOnS1(imin)) {
1091 Einf.ChangeFirstPC() = i2s.LineOnS1(imin);
1093 Einf.ChangeFirstPC()->Reverse();
1096 if (i2s.HasLineOnS2(imin)) {
1097 Einf.ChangeSecondPC() = i2s.LineOnS2(imin);
1099 Einf.ChangeSecondPC()->Reverse();
1101 } // if (i2s.Line(1)->DynamicType() != STANDARD_TYPE(Geom_BSplineCurve))
1102 else // i2s.Line(1) is BSplineCurve
1104 //Find the first curve to glue
1105 TColGeom_SequenceOfCurve Candidates;
1106 if (S1->DynamicType() == STANDARD_TYPE(Geom_CylindricalSurface) ||
1107 S1->DynamicType() == STANDARD_TYPE(Geom_ConicalSurface))
1109 for (i = 1; i <= i2s.NbLines(); i++)
1111 Handle( Geom_Curve ) aCurve = i2s.Line(i);
1112 gp_Pnt Pnt = aCurve->Value( aCurve->FirstParameter() );
1113 GeomAPI_ProjectPointOnSurf projector( Pnt, S1, Precision::Confusion() );
1115 projector.LowerDistanceParameters( U, V );
1116 if (Abs(U) <= Precision::Confusion() || Abs(U-2.*M_PI) <= Precision::Confusion())
1117 Candidates.Append( aCurve );
1120 Pnt = aCurve->Value( aCurve->LastParameter() );
1121 projector.Init( Pnt, S1, Precision::Confusion() );
1122 projector.LowerDistanceParameters( U, V );
1123 if (Abs(U) <= Precision::Confusion() || Abs(U-2.*M_PI) <= Precision::Confusion())
1126 Candidates.Append( aCurve );
1131 if(Candidates.Length() == 0)
1133 // errStat = Draft_EdgeRecomputation;
1134 // badShape = TopoDS::Edge(ite.Key());
1136 for (i = 1; i <= i2s.NbLines(); i++)
1137 Candidates.Append( i2s.Line(i) );
1142 for (i = 1; i <= i2s.NbLines(); i++)
1143 Candidates.Append( i2s.Line(i) );
1146 Handle( Geom_Curve ) FirstCurve;
1147 if (Candidates.Length() > 1)
1149 Dist2Min = RealLast();
1150 for (i = 1; i <= Candidates.Length(); i++)
1152 Handle( Geom_Curve ) aCurve = Candidates(i);
1153 gp_Pnt Pnt = aCurve->Value( aCurve->FirstParameter() );
1154 Dist2 = Pnt.SquareDistance( pfv );
1155 if (Dist2 < Dist2Min)
1158 FirstCurve = aCurve;
1163 FirstCurve = Candidates(1);
1166 TColGeom_SequenceOfCurve Curves;
1167 for (i = 1; i <= i2s.NbLines(); i++)
1168 if (FirstCurve != i2s.Line(i))
1169 Curves.Append( i2s.Line(i) );
1171 TColGeom_SequenceOfCurve ToGlue;
1172 gp_Pnt EndPoint = FirstCurve->Value( FirstCurve->LastParameter() );
1173 Standard_Boolean added = Standard_True;
1176 added = Standard_False;
1177 for (i = 1; i <= Curves.Length(); i++)
1179 Handle( Geom_Curve ) aCurve = Curves(i);
1180 gp_Pnt pfirst, plast;
1181 pfirst = aCurve->Value( aCurve->FirstParameter() );
1182 plast = aCurve->Value( aCurve->LastParameter() );
1183 if (pfirst.Distance( EndPoint ) <= Precision::Confusion())
1185 ToGlue.Append( aCurve );
1188 added = Standard_True;
1191 if (plast.Distance( EndPoint ) <= Precision::Confusion())
1194 ToGlue.Append( aCurve );
1197 added = Standard_True;
1203 if (FirstCurve.IsNull()) {
1204 errStat = Draft_EdgeRecomputation;
1205 badShape = TopoDS::Edge(ite.Key());
1209 GeomConvert_CompCurveToBSplineCurve Concat( Handle(Geom_BSplineCurve)::DownCast(FirstCurve) );
1210 for (i = 1; i <= ToGlue.Length(); i++)
1211 Concat.Add( Handle(Geom_BSplineCurve)::DownCast(ToGlue(i)), Precision::Confusion(), Standard_True );
1213 newC = Concat.BSplineCurve();
1215 TheCurve.Load( newC );
1216 Extrema_ExtPC myExtPC( pfv, TheCurve );
1217 Dist2Min = RealLast();
1218 for (i = 1; i <= myExtPC.NbExt(); i++)
1220 Dist2 = myExtPC.SquareDistance(i);
1221 if (Dist2 < Dist2Min)
1224 pmin = myExtPC.Point(i).Parameter();
1228 newC->D1(pmin,pfv,newd1);
1229 Standard_Boolean YaRev = d1fv.Dot(newd1) < 0.;
1234 if (i2s.HasLineOnS1(imin)) {
1235 Einf.ChangeFirstPC() = i2s.LineOnS1(imin);
1237 Einf.ChangeFirstPC()->Reverse();
1240 if (i2s.HasLineOnS2(imin)) {
1241 Einf.ChangeSecondPC() = i2s.LineOnS2(imin);
1243 Einf.ChangeSecondPC()->Reverse();
1246 } // else: i2s.NbLines() > 2 && S1 is Cylinder or Cone
1248 Einf.Tolerance(Max(Einf.Tolerance(), i2s.TolReached3d()));
1251 else { // case of tangency
1252 const TopoDS_Face& F1 = Einf.FirstFace();
1253 const TopoDS_Face& F2 = Einf.SecondFace();
1255 Handle(Geom_Surface) aLocalS1 = myFMap(F1).Geometry();
1256 Handle(Geom_Surface) aLocalS2 = myFMap(F2).Geometry();
1257 if (aLocalS1.IsNull() || aLocalS2.IsNull()) {
1258 errStat = Draft_EdgeRecomputation;
1259 badShape = TopoDS::Edge(ite.Key());
1262 if (aLocalS1->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1263 aLocalS1 = Handle(Geom_RectangularTrimmedSurface)::
1264 DownCast(aLocalS1)->BasisSurface();
1266 if (aLocalS2->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1267 aLocalS2 = Handle(Geom_RectangularTrimmedSurface)::
1268 DownCast(aLocalS2)->BasisSurface();
1272 //Standard_Boolean dirfound = Standard_False;
1273 if (aLocalS1->DynamicType() == STANDARD_TYPE(Geom_CylindricalSurface)) {
1275 Handle(Geom_CylindricalSurface)::DownCast(aLocalS1)->Cylinder();
1276 dirextr = cyl.Axis().Direction();
1277 //dirfound = Standard_True;
1281 else if (aLocalS1->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
1282 dirextr = Handle(Geom_SurfaceOfLinearExtrusion)::
1283 DownCast(aLocalS1)->Direction();
1284 //dirfound = Standard_True;
1287 // Here it is possible to calculate PCurve.
1288 Handle(Geom_SurfaceOfLinearExtrusion) SEL =
1289 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(aLocalS1);
1290 Handle(Geom_Circle) GCir =
1291 Handle(Geom_Circle)::DownCast(SEL->BasisCurve());
1292 if ( !GCir.IsNull()) {
1293 Standard_Real U = ElCLib::Parameter(GCir->Circ(),ptfixe);
1294 Handle(Geom2d_Line) PC1 =
1295 new Geom2d_Line(gp_Pnt2d(U,0.),gp::DY2d());
1296 Einf.ChangeFirstPC() = PC1;
1300 else if (aLocalS2->DynamicType() == STANDARD_TYPE(Geom_CylindricalSurface)) {
1302 Handle(Geom_CylindricalSurface)::DownCast(aLocalS2)->Cylinder();
1303 dirextr = cyl.Axis().Direction();
1304 // dirfound = Standard_True;
1308 else if (aLocalS2->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
1309 dirextr = Handle(Geom_SurfaceOfLinearExtrusion)::
1310 DownCast(aLocalS2)->Direction();
1311 // dirfound = Standard_True;
1314 // Here it is possible to calculate PCurve.
1315 Handle(Geom_SurfaceOfLinearExtrusion) SEL =
1316 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(aLocalS2);
1317 Handle(Geom_Circle) GCir =
1318 Handle(Geom_Circle)::DownCast(SEL->BasisCurve());
1319 if ( !GCir.IsNull()) {
1320 Standard_Real U = ElCLib::Parameter(GCir->Circ(),ptfixe);
1321 Handle(Geom2d_Line) PC2 =
1322 new Geom2d_Line(gp_Pnt2d(U,0.),gp::DY2d());
1323 Einf.ChangeSecondPC() = PC2;
1326 newC = new Geom_Line(ptfixe,dirextr);
1331 newC->D1(0.,pfv,newd1);
1332 Standard_Boolean YaRev = d1fv.Dot(newd1) <0.;
1335 if(!Einf.FirstPC().IsNull()) {
1336 Einf.ChangeFirstPC()->Reverse();
1338 if(!Einf.SecondPC().IsNull()) {
1339 Einf.ChangeSecondPC()->Reverse();
1344 Handle(Geom_TrimmedCurve) T = Handle(Geom_TrimmedCurve)::DownCast(newC);
1345 if (!T.IsNull()) newC = T->BasisCurve();
1346 Einf.ChangeGeometry() = newC;
1348 else if (!Einf.NewGeometry()){
1349 // set existing curve 3D
1350 Handle(Geom_TrimmedCurve) T = Handle(Geom_TrimmedCurve)::DownCast(C);
1351 if (!T.IsNull()) C = T->BasisCurve();
1352 Einf.ChangeGeometry() = C;
1357 // Calculate new vertices.
1359 Draft_DataMapIteratorOfDataMapOfVertexVertexInfo itv(myVMap);
1361 Handle(GeomAdaptor_HCurve) HAC = new GeomAdaptor_HCurve;
1362 Handle(GeomAdaptor_HSurface) HAS = new GeomAdaptor_HSurface;
1364 while (itv.More()) {
1365 GeomAdaptor_Curve AC;
1366 GeomAdaptor_Surface AS;
1368 Draft_VertexInfo& Vinf = myVMap(itv.Key());
1369 if (!Choose(myFMap,myEMap,itv.Key(),Vinf,AC,AS)) {
1371 // no concerted edge => alignment of two consecutive edges.
1373 Vinf.ChangeGeometry() = pvt;
1374 Vinf.InitEdgeIterator();
1375 if (Vinf.MoreEdge()) {
1376 const TopoDS_Edge& Edg1 = Vinf.Edge();
1377 //const Draft_EdgeInfo& Einf1 = myEMap(Edg1);
1378 Draft_EdgeInfo& Einf1 = myEMap(Edg1);
1379 gp_Pnt vtori = BRep_Tool::Pnt(itv.Key());
1380 //Einf1.Geometry()->D0(Vinf.Parameter(Edg1), pvt);
1381 GeomAPI_ProjectPointOnCurve Projector( vtori, Einf1.Geometry() ); //patch
1382 pvt = Projector.NearestPoint();
1385 static Standard_Integer VertexRecomp = 1;
1386 if (VertexRecomp!=0) {
1387 cout << "pori :" << vtori.X() << " " << vtori.Y() << " " << vtori.Z() << endl;
1388 cout << " Edg 1 :" << Vinf.Parameter(Edg1) << endl;
1389 cout << "pvt :" << pvt.X() << " " << pvt.Y() << " " << pvt.Z() << endl;
1393 Standard_Real dion=pvt.SquareDistance(vtori);
1395 if (Vinf.MoreEdge()) {
1396 const TopoDS_Edge& Edg2 = Vinf.Edge();
1397 //const Draft_EdgeInfo& Einf2 = myEMap(Edg2);
1398 Draft_EdgeInfo& Einf2 = myEMap(Edg2);
1401 Einf2.Geometry()->D0(Vinf.Parameter(Edg2), opvt);
1404 if (VertexRecomp!=0) {
1405 cout << " Edg 2 :" << Vinf.Parameter(Vinf.Edge()) << endl;
1406 cout << "opvt " << opvt.X() << " " << opvt.Y() << " " << opvt.Z() << endl;
1410 if (opvt.SquareDistance(vtori) < dion) {
1413 //Vinf.ChangeParameter(Edg2) = Parameter(Einf2.Geometry(), pvt);
1414 Standard_Integer done;
1415 Standard_Real param = Parameter(Einf2.Geometry(), pvt, done);
1418 S1 = myFMap(Einf2.FirstFace()).Geometry();
1419 S2 = myFMap(Einf2.SecondFace()).Geometry();
1420 Vinf.ChangeParameter(Edg2) = SmartParameter( Einf2, BRep_Tool::Tolerance(Edg2), pvt, done, S1, S2 );
1423 Vinf.ChangeParameter(Edg2) = param;
1426 Vinf.ChangeGeometry() = pvt;
1427 //Vinf.ChangeParameter(Edg1) = Parameter(Einf1.Geometry(), pvt);
1428 Standard_Integer done;
1429 Standard_Real param = Parameter(Einf1.Geometry(), pvt, done);
1432 S1 = myFMap(Einf1.FirstFace()).Geometry();
1433 S2 = myFMap(Einf1.SecondFace()).Geometry();
1434 Vinf.ChangeParameter(Edg1) = SmartParameter( Einf1, BRep_Tool::Tolerance(Edg1), pvt, done, S1, S2 );
1437 Vinf.ChangeParameter(Edg1) = param;
1443 errStat = Draft_VertexRecomputation;
1444 badShape = TopoDS::Vertex(itv.Key());
1448 IntCurveSurface_HInter myintcs;
1451 myintcs.Perform(HAC,HAS);
1453 if (!myintcs.IsDone()) {
1454 errStat = Draft_VertexRecomputation;
1455 badShape = TopoDS::Vertex(itv.Key());
1459 gp_Pnt vtori = BRep_Tool::Pnt(itv.Key());
1462 Standard_Integer nbsol = myintcs.NbPoints();
1465 Extrema_ExtCS extr( AC, AS, Precision::PConfusion(), Precision::PConfusion() );
1467 if(!extr.IsDone() || extr.NbExt() == 0) {
1468 errStat = Draft_VertexRecomputation;
1469 badShape = TopoDS::Vertex(itv.Key());
1474 Standard_Real disref = RealLast();
1475 Standard_Integer iref = 0;
1478 for (Standard_Integer i = 1; i <= extr.NbExt(); i++)
1480 extr.Points( i, Pc, Ps );
1481 Standard_Real distemp = Pc.Value().SquareDistance(vtori);
1482 if ( distemp < disref)
1488 extr.Points( iref, Pc, Ps );
1493 Standard_Real disref = RealLast();
1494 Standard_Integer iref = 0;
1495 for (Standard_Integer i = 1; i <= nbsol; i++)
1497 Standard_Real distemp = myintcs.Point(i).Pnt().SquareDistance(vtori);
1498 if ( distemp < disref)
1504 pvt = myintcs.Point(iref).Pnt();
1507 Vinf.ChangeGeometry() = pvt;
1509 for (Vinf.InitEdgeIterator();Vinf.MoreEdge(); Vinf.NextEdge()) {
1510 const TopoDS_Edge& Edg = Vinf.Edge();
1511 //const Draft_EdgeInfo& Einf = myEMap(Edg);
1512 Draft_EdgeInfo& Einf = myEMap(Edg);
1513 //Vinf.ChangeParameter(Edg) = Parameter(Einf.Geometry(),pvt);
1514 Standard_Integer done;
1515 Standard_Real param = Parameter(Einf.Geometry(), pvt, done);
1518 S1 = myFMap(Einf.FirstFace()).Geometry();
1519 S2 = myFMap(Einf.SecondFace()).Geometry();
1520 Vinf.ChangeParameter(Edg) = SmartParameter( Einf, BRep_Tool::Tolerance(Edg), pvt, done, S1, S2 );
1523 Vinf.ChangeParameter(Edg) = param;
1529 // small loop of validation/protection
1531 for (Draft_DataMapIteratorOfDataMapOfEdgeEdgeInfo ite(myEMap);
1532 ite.More(); ite.Next()) {
1533 const TopoDS_Edge& edg = TopoDS::Edge(ite.Key());
1535 TopoDS_Vertex Vf,Vl;
1536 TopExp::Vertices(edg,Vf,Vl);
1537 if (edg.Orientation() == TopAbs_REVERSED) {
1541 Standard_Real pf,pl,tolerance;
1542 if (!NewParameter(Vf,edg,pf,tolerance)) {
1543 pf = BRep_Tool::Parameter(Vf,edg);
1545 if (!NewParameter(Vl,edg,pl,tolerance)) {
1546 pl = BRep_Tool::Parameter(Vl,edg);
1549 // const Handle(Geom_Curve) gc=ite.Value().Geometry();
1550 // if (!gc.IsNull()) {
1551 // pl = gc->LastParameter();
1552 // pf = gc->FirstParameter();
1554 Handle( Geom_Curve ) theCurve = myEMap(edg).Geometry();
1555 if (theCurve->IsClosed())
1558 Standard_Real FirstPar = theCurve->FirstParameter(), LastPar = theCurve->LastParameter();
1559 Standard_Real pconf = Precision::PConfusion();
1560 if (Abs( pf - LastPar ) <= pconf)
1562 else if (Abs( pl - FirstPar ) <= pconf)
1566 pl += (LastPar-FirstPar);
1571 errStat = Draft_EdgeRecomputation;
1572 badShape = TopoDS::Edge(ite.Key());
1576 if (myVMap.IsBound( Vf ))
1577 myVMap(Vf).ChangeParameter(edg) = pf;
1578 if (myVMap.IsBound( Vl ))
1579 myVMap(Vl).ChangeParameter(edg) = pl;
1585 //=======================================================================
1586 //function : NewSurface
1588 //=======================================================================
1590 Handle(Geom_Surface) Draft_Modification::NewSurface
1591 (const Handle(Geom_Surface)& S,
1592 const TopAbs_Orientation Oris,
1593 const gp_Dir& Direction,
1594 const Standard_Real Angle,
1595 const gp_Pln& NeutralPlane)
1597 Handle(Geom_Surface) NewS;
1599 Handle(Standard_Type) TypeS = S->DynamicType();
1601 if (TypeS == STANDARD_TYPE(Geom_Plane)) {
1602 gp_Pln Pl = Handle(Geom_Plane)::DownCast(S)->Pln();
1604 Standard_Real Theta;
1605 if (FindRotation(Pl,Oris,Direction,Angle,NeutralPlane,Axe,Theta)) {
1606 if ( Abs(Theta) > Precision::Angular()) {
1607 NewS = Handle(Geom_Surface)::DownCast(S->Rotated(Axe,Theta));
1614 else if (TypeS == STANDARD_TYPE(Geom_CylindricalSurface)) {
1615 Standard_Real testdir = Direction.Dot(NeutralPlane.Axis().Direction());
1616 if (Abs(testdir) <= 1.-Precision::Angular()) {
1618 cout << "NewSurfaceCyl:Draft_Direction_and_Neutral_Perpendicular" << endl;
1622 gp_Cylinder Cy = Handle(Geom_CylindricalSurface)::DownCast(S)->Cylinder();
1623 testdir = Direction.Dot(Cy.Axis().Direction());
1624 if (Abs(testdir) <= 1.-Precision::Angular()) {
1626 cout << "NewSurfaceCyl:Draft_Direction_and_Cylinder_Perpendicular" << endl;
1630 if (Abs(Angle) > Precision::Angular())
1632 IntAna_QuadQuadGeo i2s;
1633 i2s.Perform(NeutralPlane,Cy,Precision::Angular(),Precision::Confusion());
1634 Standard_Boolean isIntDone = i2s.IsDone();
1636 if(i2s.TypeInter() == IntAna_Ellipse)
1638 const gp_Elips anEl = i2s.Ellipse(1);
1639 const Standard_Real aMajorR = anEl.MajorRadius();
1640 const Standard_Real aMinorR = anEl.MinorRadius();
1641 isIntDone = (aMajorR < 100000.0 * aMinorR);
1644 if (!isIntDone || i2s.TypeInter() != IntAna_Circle) {
1646 cout << "NewSurfaceCyl:Draft_Intersection_Neutral_Cylinder_NotDone" << endl;
1650 gp_Ax3 axcone = Cy.Position();
1651 // Pb : Where is the material???
1652 Standard_Real alpha = Angle;
1653 Standard_Boolean direct(axcone.Direct());
1654 if ((direct && Oris == TopAbs_REVERSED) ||
1655 (!direct && Oris == TopAbs_FORWARD)) {
1659 gp_Pnt Center = i2s.Circle(1).Location();
1663 Standard_Real Z = ElCLib::LineParameter(Cy.Axis(),Center);
1664 Standard_Real Rad = Cy.Radius()+Z*Tan(alpha);
1671 gp_Cone co(axcone,alpha,Rad);
1672 NewS = new Geom_ConicalSurface(co);
1678 else if (TypeS == STANDARD_TYPE(Geom_ConicalSurface)) {
1680 Standard_Real testdir = Direction.Dot(NeutralPlane.Axis().Direction());
1681 if (Abs(testdir) <= 1.-Precision::Angular()) {
1683 cout << "NewSurfaceCone:Draft_Direction_and_Neutral_Perpendicular" << endl;
1688 gp_Cone Co1 = Handle(Geom_ConicalSurface)::DownCast(S)->Cone();
1690 testdir = Direction.Dot(Co1.Axis().Direction());
1691 if (Abs(testdir) <= 1.-Precision::Angular()) {
1693 cout << "NewSurfaceCone:Draft_Direction_and_Cone_Perpendicular" << endl;
1699 IntAna_QuadQuadGeo i2s;
1700 i2s.Perform(NeutralPlane,Co1,Precision::Angular(),Precision::Confusion());
1701 if (!i2s.IsDone() || i2s.TypeInter() != IntAna_Circle) {
1703 cout << "NewSurfaceCone:Draft_Intersection_Neutral_Conical_NotDone" << endl;
1707 gp_Ax3 axcone = Co1.Position();
1708 // Pb : Where is the material???
1709 Standard_Real alpha = Angle;
1710 Standard_Boolean direct(axcone.Direct());
1711 if ((direct && Oris == TopAbs_REVERSED) ||
1712 (!direct && Oris == TopAbs_FORWARD)) {
1716 gp_Pnt Center = i2s.Circle(1).Location();
1717 if (Abs(Angle) > Precision::Angular()) {
1721 Standard_Real Z = ElCLib::LineParameter(Co1.Axis(),Center);
1722 Standard_Real Rad = i2s.Circle(1).Radius()+Z*Tan(alpha);
1729 if (Abs(alpha-Co1.SemiAngle()) < Precision::Angular()) {
1733 gp_Cone co(axcone,alpha,Rad);
1734 NewS = new Geom_ConicalSurface(co);
1739 Geom_CylindricalSurface(gp_Cylinder(axcone,i2s.Circle(1).Radius()));
1744 cout << "NewSurface:Draft_SurfNotYetImplemented" << endl;
1751 //=======================================================================
1752 //function : NewCurve
1754 //=======================================================================
1756 Handle(Geom_Curve) Draft_Modification::NewCurve
1757 (const Handle(Geom_Curve)& C,
1758 const Handle(Geom_Surface)& S,
1759 const TopAbs_Orientation Oris,
1760 const gp_Dir& Direction,
1761 const Standard_Real Angle,
1762 const gp_Pln& NeutralPlane,
1763 const Standard_Boolean )
1766 Handle(Geom_Curve) NewC;
1768 Handle(Standard_Type) TypeS = S->DynamicType();
1770 if (TypeS == STANDARD_TYPE(Geom_Plane)) {
1771 gp_Pln Pl = Handle(Geom_Plane)::DownCast(S)->Pln();
1773 Standard_Real Theta;
1774 if (FindRotation(Pl,Oris,Direction,Angle,NeutralPlane,Axe,Theta)) {
1775 if ( Abs(Theta) > Precision::Angular()) {
1776 NewC = Handle(Geom_Curve)::DownCast(C->Rotated(Axe,Theta));
1786 if (C->DynamicType() != STANDARD_TYPE(Geom_Line)) {
1791 gp_Lin lin = Handle(Geom_Line)::DownCast(C)->Lin();
1792 // Standard_Real testdir = Direction.Dot(lin.Direction());
1793 // if (Abs(testdir) <= 1.-Precision::Angular()) {
1797 if (TypeS == STANDARD_TYPE(Geom_CylindricalSurface)) {
1801 gp_Cylinder Cy = Handle(Geom_CylindricalSurface)::DownCast(S)->Cylinder();
1802 ElSLib::Parameters(Cy,lin.Location(),U,V);
1803 ElSLib::D1(U,V,Cy,pbid,d1u,d1v);
1804 Norm = d1u.Crossed(d1v);
1806 else if (TypeS == STANDARD_TYPE(Geom_ConicalSurface)) {
1810 gp_Cone Co = Handle(Geom_ConicalSurface)::DownCast(S)->Cone();
1811 ElSLib::Parameters(Co,lin.Location(),U,V);
1812 ElSLib::D1(U,V,Co,pbid,d1u,d1v);
1813 Norm = d1u.Crossed(d1v);
1816 IntAna_IntConicQuad ilipl(lin,NeutralPlane,Precision::Angular());
1817 if (ilipl.IsDone() && ilipl.NbPoints() != 0){
1818 if (Oris == TopAbs_REVERSED) {
1821 gp_Ax1 axrot(ilipl.Point(1), Norm.Crossed(Direction));
1822 gp_Lin lires = gp_Lin(gp_Ax1(ilipl.Point(1),Direction)).
1823 Rotated(axrot,Angle);
1824 if (lires.Direction().Dot(lin.Direction()) < 0.) {
1827 NewC = new Geom_Line(lires);
1833 //=======================================================================
1836 //=======================================================================
1838 static Standard_Boolean Choose(const Draft_DataMapOfFaceFaceInfo& theFMap,
1839 Draft_DataMapOfEdgeEdgeInfo& theEMap,
1840 const TopoDS_Vertex& Vtx,
1841 Draft_VertexInfo& Vinf,
1842 GeomAdaptor_Curve& AC,
1843 GeomAdaptor_Surface& AS)
1846 Vinf.InitEdgeIterator();
1848 // Find a regular edge with null SecondFace
1849 while (Vinf.MoreEdge()) {
1850 const TopoDS_Edge& E1 = Vinf.Edge();
1851 const Draft_EdgeInfo& Einf1 = theEMap(E1);
1852 if (Einf1.SecondFace().IsNull()) {
1856 GeomAbs_Shape te = BRep_Tool::Continuity(E1,Einf1.FirstFace(),
1857 Einf1.SecondFace());
1858 if (te >= GeomAbs_G1) {
1864 if (!Vinf.MoreEdge()) { // take the first edge
1865 Vinf.InitEdgeIterator();
1868 const TopoDS_Edge& Eref = Vinf.Edge();
1869 //const Draft_EdgeInfo& Einf = theEMap(Eref);
1870 Draft_EdgeInfo& Einf = theEMap(Eref);
1872 AC.Load(Einf.Geometry());
1874 Standard_Real f,l,prm;
1875 TopLoc_Location Loc;
1876 Handle(Geom_Curve) C = BRep_Tool::Curve(Eref,Loc,f,l);
1877 C = Handle(Geom_Curve)::DownCast(C->Transformed(Loc.Transformation()));
1879 //prm = Parameter(C,BRep_Tool::Pnt(Vtx));
1880 Standard_Integer done;
1881 Standard_Real param = Parameter( C, BRep_Tool::Pnt(Vtx), done );
1884 Handle( Geom_Surface ) S1 = theFMap(Einf.FirstFace()).Geometry();
1885 Handle( Geom_Surface ) S2 = theFMap(Einf.SecondFace()).Geometry();
1886 prm = SmartParameter( Einf, BRep_Tool::Tolerance(Eref), BRep_Tool::Pnt(Vtx), done, S1, S2 );
1890 C->D1(prm,ptbid,tgref);
1893 Vinf.InitEdgeIterator();
1894 while (Vinf.MoreEdge()) {
1895 // Find a non tangent edge
1896 const TopoDS_Edge& Edg = Vinf.Edge();
1897 if (!Edg.IsSame(Eref)) {
1898 //const Draft_EdgeInfo& Einfo = theEMap(Edg);
1899 Draft_EdgeInfo& Einfo = theEMap(Edg);
1900 if (!Einfo.SecondFace().IsNull() &&
1901 BRep_Tool::Continuity(Edg,Einfo.FirstFace(),Einfo.SecondFace())
1903 C = BRep_Tool::Curve(Edg,Loc,f,l);
1904 C = Handle(Geom_Curve)::DownCast(C->Transformed(Loc.Transformation()));
1905 //prm = Parameter(C,BRep_Tool::Pnt(Vtx));
1906 Standard_Integer anewdone;
1907 Standard_Real anewparam = Parameter( C, BRep_Tool::Pnt(Vtx), anewdone );
1910 Handle( Geom_Surface ) S1 = theFMap(Einfo.FirstFace()).Geometry();
1911 Handle( Geom_Surface ) S2 = theFMap(Einfo.SecondFace()).Geometry();
1912 prm = SmartParameter( Einfo, BRep_Tool::Tolerance(Edg), BRep_Tool::Pnt(Vtx), anewdone, S1, S2 );
1917 C->D1(prm,ptbid,tg);
1918 if (tg.CrossMagnitude(tgref) > Precision::Confusion()) {
1925 if (!Vinf.MoreEdge()) {
1926 return Standard_False;
1929 const Draft_EdgeInfo& Einf2 = theEMap(Vinf.Edge());
1930 if (!Einf.SecondFace().IsNull()) {
1932 if (Einf2.FirstFace().IsSame(Einf.FirstFace()) ||
1933 Einf2.FirstFace().IsSame(Einf.SecondFace())) {
1934 AS.Load(theFMap(Einf2.SecondFace()).Geometry());
1937 AS.Load(theFMap(Einf2.FirstFace()).Geometry());
1941 if (Einf2.FirstFace().IsSame(Einf.FirstFace())) {
1942 AS.Load(theFMap(Einf2.SecondFace()).Geometry());
1945 AS.Load(theFMap(Einf2.FirstFace()).Geometry());
1948 return Standard_True;
1952 //=======================================================================
1953 //function : Parameter
1955 //=======================================================================
1957 static Standard_Real Parameter(const Handle(Geom_Curve)& C,
1959 Standard_Integer& done)
1962 Handle(Geom_Curve) cbase = C;
1963 Handle(Standard_Type) ctyp = C->DynamicType();
1964 if (ctyp == STANDARD_TYPE(Geom_TrimmedCurve)) {
1965 cbase = Handle(Geom_TrimmedCurve)::DownCast(C)->BasisCurve();
1966 ctyp = cbase->DynamicType();
1968 Standard_Real param;
1969 if (ctyp == STANDARD_TYPE(Geom_Line)) {
1970 param = ElCLib::Parameter(Handle(Geom_Line)::DownCast(cbase)->Lin(),P);
1972 else if (ctyp == STANDARD_TYPE(Geom_Circle)) {
1973 param = ElCLib::Parameter(Handle(Geom_Circle)::DownCast(cbase)->Circ(),P);
1974 if (Abs(2.*M_PI-param) <=Epsilon(2.*M_PI)) {
1978 else if (ctyp == STANDARD_TYPE(Geom_Ellipse)) {
1979 param = ElCLib::Parameter(Handle(Geom_Ellipse)::DownCast(cbase)->Elips(),P);
1980 if (Abs(2.*M_PI-param) <=Epsilon(2.*M_PI)) {
1984 else if (ctyp == STANDARD_TYPE(Geom_Parabola)) {
1985 param = ElCLib::Parameter(Handle(Geom_Parabola)::DownCast(cbase)->Parab(),P);
1987 else if (ctyp == STANDARD_TYPE(Geom_Hyperbola)) {
1988 param = ElCLib::Parameter(Handle(Geom_Hyperbola)::DownCast(cbase)->Hypr(),P);
1991 GeomAdaptor_Curve TheCurve(C);
1992 Extrema_ExtPC myExtPC(P,TheCurve);
1993 if (!myExtPC.IsDone()) {
1994 Standard_Failure::Raise();
1996 if (myExtPC.NbExt() >= 1) {
1997 Standard_Real Dist2, Dist2Min = myExtPC.SquareDistance(1);
1998 Standard_Integer j, jmin = 1;
1999 for (j = 2; j <= myExtPC.NbExt(); j++) {
2000 Dist2 = myExtPC.SquareDistance(j);
2001 if (Dist2 < Dist2Min) {
2006 param = myExtPC.Point(jmin).Parameter();
2009 Standard_Real dist1_2,dist2_2;
2011 myExtPC.TrimmedSquareDistances(dist1_2,dist2_2,p1b,p2b);
2012 if (dist1_2 < dist2_2) {
2014 param = TheCurve.FirstParameter();
2018 param = TheCurve.LastParameter();
2022 if (cbase->IsPeriodic()) {
2023 Standard_Real Per = cbase->Period();
2024 Standard_Real Tolp = Precision::Parametric(Precision::Confusion());
2025 if (Abs(Per-param) <= Tolp) {
2033 //=======================================================================
2034 //function : SmartParameter
2036 //=======================================================================
2038 static Standard_Real SmartParameter(Draft_EdgeInfo& Einf,
2039 const Standard_Real EdgeTol,
2041 const Standard_Integer sign,
2042 const Handle(Geom_Surface)& S1,
2043 const Handle(Geom_Surface)& S2)
2045 Handle( Geom2d_Curve ) NewC2d;
2046 Standard_Real Tol = Precision::Confusion();
2047 Standard_Real Etol = EdgeTol;
2049 Handle( Geom2d_Curve ) pcu1 = Einf.FirstPC();
2050 Handle( Geom2d_Curve ) pcu2 = Einf.SecondPC();
2054 Handle( Geom_Curve ) theCurve = Einf.Geometry();
2055 pcu1 = GeomProjLib::Curve2d( theCurve, theCurve->FirstParameter(), theCurve->LastParameter(), S1, Etol );
2056 Einf.ChangeFirstPC() = pcu1;
2060 Handle( Geom_Curve ) theCurve = Einf.Geometry();
2061 pcu2 = GeomProjLib::Curve2d( theCurve, theCurve->FirstParameter(), theCurve->LastParameter(), S2, Etol );
2062 Einf.ChangeSecondPC() = pcu2;
2065 GeomAPI_ProjectPointOnSurf Projector( Pnt, S1 );
2067 Projector.LowerDistanceParameters( U, V );
2069 NewC2d = Einf.FirstPC();
2070 if (NewC2d->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve))
2071 NewC2d = (Handle(Geom2d_TrimmedCurve)::DownCast(NewC2d))->BasisCurve();
2073 gp_Pnt2d P2d( U, V );
2074 Geom2dAPI_ProjectPointOnCurve Projector2d( P2d, NewC2d );
2075 if (Projector2d.NbPoints() == 0 || Projector2d.LowerDistance() > Tol)
2077 Handle( Geom2d_BSplineCurve ) BCurve;
2078 if (NewC2d->DynamicType() != STANDARD_TYPE(Geom2d_BSplineCurve))
2079 BCurve = Geom2dConvert::CurveToBSplineCurve( NewC2d );
2081 BCurve = Handle( Geom2d_BSplineCurve )::DownCast( NewC2d );
2084 TColgp_Array1OfPnt2d PntArray( 1, 2 );
2086 PntArray(2) = BCurve->Pole(1);
2087 Handle( Geom2d_BezierCurve ) Patch = new Geom2d_BezierCurve( PntArray );
2088 Geom2dConvert_CompCurveToBSplineCurve Concat( BCurve, Convert_QuasiAngular );
2089 Concat.Add( Patch, Tol, Standard_False );
2090 BCurve = Concat.BSplineCurve();
2094 TColgp_Array1OfPnt2d PntArray( 1, 2 );
2095 PntArray(1) = BCurve->Pole( BCurve->NbPoles() );
2097 Handle( Geom2d_BezierCurve ) Patch = new Geom2d_BezierCurve( PntArray );
2098 Geom2dConvert_CompCurveToBSplineCurve Concat( BCurve, Convert_QuasiAngular );
2099 Concat.Add( Patch, Tol, Standard_True );
2100 BCurve = Concat.BSplineCurve();
2104 Einf.ChangeFirstPC() = NewC2d;
2105 Handle( Geom2dAdaptor_HCurve ) hcur = new Geom2dAdaptor_HCurve( NewC2d );
2106 Handle( GeomAdaptor_HSurface ) hsur = new GeomAdaptor_HSurface( S1 );
2107 Adaptor3d_CurveOnSurface cons( hcur, hsur );
2108 Handle( Adaptor3d_HCurveOnSurface ) hcons = new Adaptor3d_HCurveOnSurface( cons );
2109 Handle( GeomAdaptor_HSurface ) hsur2 = new GeomAdaptor_HSurface( S2 );
2110 ProjLib_CompProjectedCurve ProjCurve( hsur2, hcons, Tol, Tol );
2111 Handle(ProjLib_HCompProjectedCurve) HProjector = new ProjLib_HCompProjectedCurve();
2112 HProjector->Set( ProjCurve );
2113 Standard_Real Udeb, Ufin;
2114 ProjCurve.Bounds(1, Udeb, Ufin);
2115 Standard_Integer MaxSeg = 20 + HProjector->NbIntervals(GeomAbs_C3);
2116 Approx_CurveOnSurface appr( HProjector, hsur2, Udeb, Ufin, Tol,
2117 GeomAbs_C1, 10, MaxSeg,
2118 Standard_False, Standard_False );
2119 Einf.ChangeSecondPC() = appr.Curve2d();
2120 Einf.ChangeGeometry() = appr.Curve3d();
2121 Einf.SetNewGeometry( Standard_True );
2124 return Einf.Geometry()->FirstParameter();
2126 return Einf.Geometry()->LastParameter();
2130 //=======================================================================
2131 //function : Orientation
2133 //=======================================================================
2135 static TopAbs_Orientation Orientation(const TopoDS_Shape& S,
2136 const TopoDS_Face& F)
2139 // change porting NT
2141 TopExp_Explorer expl ;
2144 while (expl.More()) {
2145 if (TopoDS::Face(expl.Current()).IsSame(F)) {
2146 return expl.Current().Orientation();
2150 return TopAbs_FORWARD;
2154 //=======================================================================
2155 //function : FindRotation
2157 //=======================================================================
2159 static Standard_Boolean FindRotation(const gp_Pln& Pl,
2160 const TopAbs_Orientation Oris,
2161 const gp_Dir& Direction,
2162 const Standard_Real Angle,
2163 const gp_Pln& NeutralPlane,
2165 Standard_Real& theta)
2167 IntAna_QuadQuadGeo i2pl(Pl,NeutralPlane,
2168 Precision::Angular(),Precision::Confusion());
2170 if (i2pl.IsDone() && i2pl.TypeInter() == IntAna_Line) {
2171 gp_Lin li = i2pl.Line(1);
2172 // Try to turn around this line
2173 gp_Dir nx = li.Direction();
2174 gp_Dir ny = Pl.Axis().Direction().Crossed(nx);
2175 Standard_Real a = Direction.Dot(nx);
2176 if (Abs(a) <=1-Precision::Angular()) {
2177 Standard_Real b = Direction.Dot(ny);
2178 Standard_Real c = Direction.Dot(Pl.Axis().Direction());
2179 Standard_Boolean direct(Pl.Position().Direct());
2180 if ((direct && Oris == TopAbs_REVERSED) ||
2181 (!direct && Oris == TopAbs_FORWARD)) {
2185 Standard_Real denom = Sqrt(1-a*a);
2186 Standard_Real Sina = Sin(Angle);
2187 if (denom>Abs(Sina)) {
2188 Standard_Real phi = ATan2(b/denom,c/denom);
2189 Standard_Real theta0 = ACos(Sina/denom);
2190 theta = theta0 - phi;
2191 if (Cos(theta) <0.) {
2192 theta = -theta0 -phi;
2194 // modified by NIZHNY-EAP Tue Nov 16 15:51:38 1999 ___BEGIN___
2195 while (Abs(theta)>M_PI) {
2196 theta = theta + M_PI*(theta<0 ? 1 : -1);
2198 // modified by NIZHNY-EAP Tue Nov 16 15:53:32 1999 ___END___
2199 Axe = li.Position();
2200 return Standard_True;
2204 return Standard_False;