1 // Created on: 1994-12-02
2 // Created by: Jacques GOUSSARD
3 // Copyright (c) 1994-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.
17 #include <Draft_Modification.jxx>
19 #include <BRep_Tool.hxx>
20 #include <BRep_Builder.hxx>
22 #include <BRepLib_MakeFace.hxx>
24 #include <TopLoc_Location.hxx>
25 #include <TopExp_Explorer.hxx>
26 #include <TopTools_ListIteratorOfListOfShape.hxx>
28 #include <Draft_DataMapIteratorOfDataMapOfFaceFaceInfo.hxx>
29 #include <Draft_DataMapIteratorOfDataMapOfEdgeEdgeInfo.hxx>
30 #include <Draft_DataMapIteratorOfDataMapOfVertexVertexInfo.hxx>
31 #include <Draft_FaceInfo.hxx>
32 #include <Draft_EdgeInfo.hxx>
33 #include <Draft_VertexInfo.hxx>
34 #include <BRep_Tool.hxx>
35 #include <BRep_Tool.hxx>
37 #include <Geom_Surface.hxx>
38 #include <Geom_RectangularTrimmedSurface.hxx>
41 #include <Geom2d_Line.hxx>
42 #include <Geom_Plane.hxx>
43 #include <Geom_SurfaceOfLinearExtrusion.hxx>
44 #include <Geom_CylindricalSurface.hxx>
45 #include <Geom_ConicalSurface.hxx>
46 #include <Geom_Curve.hxx>
47 #include <Geom_Line.hxx>
48 #include <Geom_Circle.hxx>
49 #include <Geom_Ellipse.hxx>
50 #include <Geom_Parabola.hxx>
51 #include <Geom_Hyperbola.hxx>
52 #include <Geom_TrimmedCurve.hxx>
53 #include <GeomAdaptor_Curve.hxx>
54 #include <GeomAdaptor_Surface.hxx>
55 #include <Adaptor3d_SurfaceOfLinearExtrusion.hxx>
60 #include <gp_Circ.hxx>
61 #include <gp_Elips.hxx>
62 #include <gp_Parab.hxx>
63 #include <gp_Hypr.hxx>
65 #include <IntCurveSurface_HInter.hxx>
66 #include <GeomInt_IntSS.hxx>
67 #include <IntCurveSurface_IntersectionPoint.hxx>
68 #include <IntAna_QuadQuadGeo.hxx>
69 #include <IntAna_IntConicQuad.hxx>
71 #include <Extrema_ExtPC.hxx>
72 #include <BRepExtrema_ExtPC.hxx>
73 #include <BRepExtrema_ExtCF.hxx>
75 #include <Standard_DomainError.hxx>
76 #include <Standard_Failure.hxx>
77 #include <Standard_NotImplemented.hxx>
79 #include <TopTools_MapOfShape.hxx>
80 #include <TopTools_MapIteratorOfMapOfShape.hxx>
83 #include <Precision.hxx>
86 #include <BRepTools.hxx>
90 #include <GeomAdaptor_HCurve.hxx>
91 #include <GeomAdaptor_HSurface.hxx>
92 #include <GeomAPI_ProjectPointOnSurf.hxx>
94 #include <GeomAPI_ProjectPointOnCurve.hxx>
96 #include <Geom2d_TrimmedCurve.hxx>
97 #include <Geom2dAPI_ProjectPointOnCurve.hxx>
98 #include <Geom2d_BSplineCurve.hxx>
99 #include <Geom2dConvert.hxx>
100 #include <Geom2dAdaptor_HCurve.hxx>
101 #include <Adaptor3d_CurveOnSurface.hxx>
103 #include <GeomProjLib.hxx>
104 #include <TColgp_Array1OfPnt2d.hxx>
105 #include <Geom2d_BezierCurve.hxx>
106 #include <Geom2dConvert_CompCurveToBSplineCurve.hxx>
108 #include <Adaptor3d_HCurveOnSurface.hxx>
109 #include <ProjLib_CompProjectedCurve.hxx>
110 #include <ProjLib_HCompProjectedCurve.hxx>
111 #include <Approx_CurveOnSurface.hxx>
113 #include <GeomConvert_CompCurveToBSplineCurve.hxx>
116 static Standard_Boolean Choose(const Draft_DataMapOfFaceFaceInfo&,
117 Draft_DataMapOfEdgeEdgeInfo&,
118 const TopoDS_Vertex&,
121 GeomAdaptor_Surface&);
123 static Standard_Real Parameter(const Handle(Geom_Curve)&,
127 static Standard_Real SmartParameter(Draft_EdgeInfo&,
128 const Standard_Real EdgeTol,
130 const Standard_Integer,
131 const Handle(Geom_Surface)&,
132 const Handle(Geom_Surface)&);
134 static TopAbs_Orientation Orientation(const TopoDS_Shape&,
137 static Standard_Boolean FindRotation(const gp_Pln&,
138 const TopAbs_Orientation,
146 //=======================================================================
147 //function : InternalAdd
149 //=======================================================================
151 Standard_Boolean Draft_Modification::InternalAdd(const TopoDS_Face& F,
152 const gp_Dir& Direction,
153 const Standard_Real Angle,
154 const gp_Pln& NeutralPlane,
155 const Standard_Boolean Flag)
158 if (myFMap.IsBound(F)) {
159 return (badShape.IsNull());
162 TopAbs_Orientation oris = Orientation(myShape,F);
164 //gp_Dir NewDirection = Direction;
165 //Standard_Real NewAngle = Angle;
166 Handle(Geom_Surface) S = BRep_Tool::Surface(F,Lo);
167 S = Handle(Geom_Surface)::DownCast(S->Transformed(Lo.Transformation()));
168 if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
169 S = Handle(Geom_RectangularTrimmedSurface)::DownCast(S)->BasisSurface();
171 Handle(Geom_Surface) NewS;
172 Handle(Geom_Circle) theCircle;
174 Standard_Boolean postponed = (Flag == Standard_False);
176 Handle(Standard_Type) typS = S->DynamicType();
177 if (typS == STANDARD_TYPE(Geom_CylindricalSurface) ||
178 typS == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
180 if (typS == STANDARD_TYPE(Geom_CylindricalSurface)) {
182 Handle(Geom_CylindricalSurface)::DownCast(S)->Cylinder();
183 gp_Ax1 axcyl = cyl.Axis();
184 Cir = ElSLib::CylinderVIso( cyl.Position(), cyl.Radius(), 0.);
185 gp_Vec VV(cyl.Location(),NeutralPlane.Location());
186 Cir.Translate(VV.Dot(axcyl.Direction())*axcyl.Direction());
189 Handle(Geom_Curve) Cbas =
190 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(S)->BasisCurve();
192 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(S)->Direction();
194 if (Cbas->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
195 Cbas = Handle(Geom_TrimmedCurve)::DownCast(Cbas)->BasisCurve();
197 if (Cbas->IsKind(STANDARD_TYPE(Geom_Circle))) {
198 Cir = Handle(Geom_Circle)::DownCast(Cbas)->Circ();
199 gp_Dir dircir = Cir.Axis().Direction();
200 if (!Direction.IsParallel(dircir,Precision::Angular())) {
202 errStat = Draft_FaceRecomputation;
203 return Standard_False;
208 errStat = Draft_FaceRecomputation;
209 return Standard_False;
212 gp_Ax3 Axis = NeutralPlane.Position();
214 gp_Vec(Cir.Location(),Axis.Location()).
215 Dot(Axis.Direction());
216 Standard_Real Cos = theDirextr.Dot(Axis.Direction());
217 gp_Vec VV = ( L / Cos) * theDirextr;
221 theCircle = new Geom_Circle(Cir);
225 postponed = Standard_False;
231 NewS = NewSurface(S,oris,Direction,Angle,NeutralPlane);
234 errStat = Draft_FaceRecomputation;
235 return Standard_False;
237 // To avoid some problems with infinite restrictions
238 const Handle(Standard_Type)& typs = NewS->DynamicType();
239 if (typs == STANDARD_TYPE(Geom_CylindricalSurface) ||
240 typs == STANDARD_TYPE(Geom_ConicalSurface)) {
241 Standard_Real umin,umax,vmin,vmax;
242 BRepTools::UVBounds(F,umin,umax,vmin,vmax);
243 if (!Precision::IsNegativeInfinite(vmin) &&
244 !Precision::IsPositiveInfinite(vmax)) {
245 Standard_Real deltav = 10.*(vmax-vmin);
246 if(typs == STANDARD_TYPE(Geom_CylindricalSurface)) {
247 vmin = vmin - deltav;
248 vmax = vmax + deltav;
251 gp_Cone Co = Handle(Geom_ConicalSurface)::DownCast(NewS)->Cone();
252 Standard_Real Vapex = - Co.RefRadius()/Sin(Co.SemiAngle());
253 if (vmin < Vapex) { // vmax should not exceed Vapex
254 if (vmax + deltav > Vapex) {
256 vmin = vmin - 10.*(vmax - vmin);
257 // JAG debug to avoid apex
258 vmax = vmax-Precision::Confusion();
261 vmin = vmin - deltav;
262 vmax = vmax + deltav;
265 else { // Vapex <= vmin < vmax
266 if (vmin - deltav < Vapex) {
268 vmax = vmax + 10.*(vmax - vmin);
269 // JAG debug to avoid apex
270 vmin = vmin+Precision::Confusion();
273 vmin = vmin - deltav;
274 vmax = vmax + deltav;
278 NewS = new Geom_RectangularTrimmedSurface(NewS,0.,2.*M_PI,vmin,vmax);
283 if (postponed || S != NewS) {
284 Draft_FaceInfo FI(NewS,Standard_True);
285 FI.RootFace(curFace);
288 myFMap(F).ChangeCurve() = theCircle;
292 TopExp_Explorer expl(F,TopAbs_EDGE);
293 TopTools_MapOfShape MapOfE;
294 while (expl.More() && badShape.IsNull()) {
295 const TopoDS_Edge& edg = TopoDS::Edge(expl.Current());
296 if (!myEMap.IsBound(edg)) {
297 Standard_Boolean addedg = Standard_False;
298 Standard_Boolean addface = Standard_False;
300 // if (BRep_Tool::IsClosed(edg,F)) {
301 if (BRepTools::IsReallyClosed(edg,F)) {
302 addedg = Standard_True;
303 addface = Standard_False;
306 // Find the other face containing the edge.
307 TopTools_ListIteratorOfListOfShape it;
308 it.Initialize(myEFMap.FindFromKey(edg));
309 Standard_Integer nbother = 0;
311 if (!it.Value().IsSame(F)) {
312 if (OtherF.IsNull()) {
313 OtherF = TopoDS::Face(it.Value());
321 errStat = Draft_EdgeRecomputation;
323 else if (! OtherF.IsNull() &&
324 BRep_Tool::Continuity(edg,F,OtherF) >= GeomAbs_G1) {
325 addface= Standard_True;
326 addedg = Standard_True;
328 else if (nbother == 0) {
334 myFMap(F).Add(OtherF);
338 Handle(Geom_Curve) C = BRep_Tool::Curve(edg,L,f,l);
339 C = Handle(Geom_Curve)::DownCast(C->Transformed(L));
340 if (C->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) {
341 C = Handle(Geom_TrimmedCurve)::DownCast(C)->BasisCurve();
343 Handle(Geom_Curve) NewC;
344 Draft_EdgeInfo EInf(Standard_True);
350 Handle(Geom_Line) aLocalGeom = Handle(Geom_Line)::DownCast(C);
351 if (aLocalGeom.IsNull()) {
353 errStat = Draft_EdgeRecomputation;
356 gp_Lin lin = aLocalGeom->Lin();
357 IntAna_IntConicQuad ilipl(lin,NeutralPlane,Precision::Angular());
358 if (ilipl.IsDone() && ilipl.NbPoints() != 0){
359 EInf.Tangent(ilipl.Point(1));
363 errStat = Draft_EdgeRecomputation;
368 NewC = NewCurve(C,S,oris,Direction,Angle,NeutralPlane, Flag);
371 errStat = Draft_EdgeRecomputation;
375 Handle(Geom_TrimmedCurve) T = Handle(Geom_TrimmedCurve)::DownCast(NewC);
376 if (!T.IsNull()) NewC = T->BasisCurve();
377 EInf.ChangeGeometry() = NewC;
379 EInf.RootFace(curFace);
380 myEMap.Bind(edg,EInf);
383 Standard_Boolean Fl = Flag;
384 Handle(Geom_Surface) alocalSurface = BRep_Tool::Surface(OtherF,Lo);
385 if (alocalSurface->DynamicType() ==
386 STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
387 alocalSurface = Handle(Geom_RectangularTrimmedSurface)::
388 DownCast(alocalSurface)->BasisSurface();
390 Handle(Standard_Type) typS = alocalSurface->DynamicType();
391 if (typS == STANDARD_TYPE(Geom_CylindricalSurface) ||
392 typS == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
393 if ( myFMap.IsBound(F)) {
394 if ( Flag == Standard_False && !postponed) {
396 TopTools_MapIteratorOfMapOfShape itm(MapOfE);
397 for ( ; itm.More(); itm.Next())
398 myEMap.UnBind(TopoDS::Edge(itm.Key()));
402 InternalAdd(OtherF,Direction,Angle,NeutralPlane, Fl);
408 return (badShape.IsNull());
412 //=======================================================================
413 //function : Propagate
415 //=======================================================================
417 Standard_Boolean Draft_Modification::Propagate ()
420 if (!badShape.IsNull()) return Standard_False;
422 Draft_DataMapIteratorOfDataMapOfFaceFaceInfo itf(myFMap);
424 // Set all edges and vertices of modified faces
428 TopExp_Explorer editer;
429 TopExp_Explorer vtiter;
432 const TopoDS_Face& Fc = itf.Key();
434 // Exploration of the edges of the face
435 editer.Init(Fc,TopAbs_EDGE);
436 while (editer.More()) {
437 E = TopoDS::Edge(editer.Current());
439 if (!myEMap.IsBound(E)) {
440 Draft_EdgeInfo EInf(Standard_True);
445 // Exploration of the vertices of the edge
446 vtiter.Init(E,TopAbs_VERTEX);
447 while (vtiter.More()) {
448 V = TopoDS::Vertex(vtiter.Current());
449 if (!myVMap.IsBound(V)) {
450 Draft_VertexInfo VInf;
455 myVMap(V).ChangeParameter(E) = BRep_Tool::Parameter(V, E);
465 Standard_Boolean found;
467 // Set edges containing modified vertices.
469 Draft_DataMapIteratorOfDataMapOfVertexVertexInfo itv(myVMap);
472 const TopoDS_Vertex& Vt = itv.Key();
474 // Exploration of the ancestors of the vertex
475 anc.Init(myShape,TopAbs_EDGE);
478 E = TopoDS::Edge(anc.Current());
479 vtiter.Init(E,TopAbs_VERTEX);
480 found = Standard_False;
481 while (vtiter.More()) {
482 if (Vt.IsSame(TopoDS::Vertex(vtiter.Current()))) {
483 found = Standard_True;
489 if (!myEMap.IsBound(E)) {
490 Draft_EdgeInfo EInf(Standard_False);
494 myVMap(Vt).ChangeParameter(E) = BRep_Tool::Parameter(Vt, E);
502 // Set faces containing modified edges
504 Draft_DataMapIteratorOfDataMapOfEdgeEdgeInfo ite(myEMap);
507 const TopoDS_Edge& Ed = ite.Key();
508 TopTools_ListIteratorOfListOfShape it;
509 for (it.Initialize(myEFMap.FindFromKey(Ed)); it.More(); it.Next()) {
510 F = TopoDS::Face(it.Value());
511 if (!myFMap.IsBound(F)) {
513 Handle(Geom_Surface) S = BRep_Tool::Surface(F,L);
514 Handle(Geom_Surface) NewS =
515 Handle(Geom_Surface)::DownCast(S->Transformed(L.Transformation()));
517 const Handle(Standard_Type)& typs = S->DynamicType();
518 if (typs == STANDARD_TYPE(Geom_CylindricalSurface) ||
519 typs == STANDARD_TYPE(Geom_ConicalSurface)) {
520 Standard_Real umin,umax,vmin,vmax;
521 BRepTools::UVBounds(F,umin,umax,vmin,vmax);
522 if (!Precision::IsNegativeInfinite(vmin) &&
523 !Precision::IsPositiveInfinite(vmax)) {
524 Standard_Real deltav = 10.*(vmax-vmin);
525 vmin = vmin - deltav;
526 vmax = vmax + deltav;
528 new Geom_RectangularTrimmedSurface(NewS,0.,2.*M_PI,vmin,vmax);
532 Draft_FaceInfo FInf(NewS,Standard_False);
540 // Try to add faces for free borders...
542 ite.Initialize(myEMap);
543 for (; ite.More(); ite.Next()) {
544 Draft_EdgeInfo& Einf = myEMap(ite.Key());
545 if (Einf.NewGeometry() && Einf.Geometry().IsNull() &&
546 Einf.SecondFace().IsNull()) {
549 Handle(Geom_Surface) S1 = BRep_Tool::Surface(Einf.FirstFace(),Loc);
550 S1 = Handle(Geom_Surface)::
551 DownCast(S1->Transformed(Loc.Transformation()));
552 Handle(Geom_Surface) S2;
555 Handle(Geom_Curve) C = BRep_Tool::Curve(ite.Key(),Loc,f,l);
556 C = Handle(Geom_Curve)::DownCast(C->Transformed(Loc.Transformation()));
557 if (C->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) {
558 C = Handle(Geom_TrimmedCurve)::DownCast(C)->BasisCurve();
560 if (!S1->IsKind(STANDARD_TYPE(Geom_Plane))) {
561 if (C->IsKind(STANDARD_TYPE(Geom_Conic))) {
562 gp_Ax3 thePl(Handle(Geom_Conic)::DownCast(C)->Position());
563 S2 = new Geom_Plane(thePl);
565 else if (C->DynamicType() == STANDARD_TYPE(Geom_Line)) {
567 if (S1->DynamicType()== STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
568 axis = Handle(Geom_ElementarySurface)::DownCast
569 (Handle(Geom_RectangularTrimmedSurface)::DownCast(S1)->
570 BasisSurface())->Axis();
573 axis = Handle(Geom_ElementarySurface)::DownCast(S1)->Axis();
575 gp_Vec they(axis.Location(), C->Value(0.));
576 gp_Dir axz(axis.Direction().Crossed(they));
577 S2=new Geom_Plane(gp_Ax3(axis.Location(),axz,axis.Direction()));
581 badShape = TopoDS::Edge(ite.Key());
582 errStat = Draft_EdgeRecomputation;
583 break; // leave from for
586 else { // on the plane
587 Draft_DataMapIteratorOfDataMapOfVertexVertexInfo anewitv(myVMap);
588 while (anewitv.More()) {
589 Draft_VertexInfo& Vinf = myVMap(anewitv.Key());
590 for (Vinf.InitEdgeIterator();Vinf.MoreEdge();Vinf.NextEdge()) {
591 if (Vinf.Edge().IsSame(ite.Key())) {
595 if (Vinf.MoreEdge()) {
596 for (Vinf.InitEdgeIterator();Vinf.MoreEdge();Vinf.NextEdge()) {
597 const TopoDS_Edge& edg = Vinf.Edge();
598 if (!edg.IsSame(ite.Key())) {
599 if (!myEMap(edg).FirstFace().IsSame(Einf.FirstFace()) &&
600 (myEMap(edg).SecondFace().IsNull() ||
601 !myEMap(edg).SecondFace().IsSame(Einf.FirstFace()))) {
606 if (Vinf.MoreEdge()) {
607 Handle(Geom_Curve) C2 = BRep_Tool::Curve(Vinf.Edge(), Loc,f,l);
608 Handle(GeomAdaptor_HCurve) HCur;
610 C2 = Handle(Geom_Curve)::DownCast
611 (C2->Transformed(Loc.Transformation()));
612 if (C2->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) {
613 C2 = Handle(Geom_TrimmedCurve)::DownCast(C2)->BasisCurve();
615 if (C->DynamicType() == STANDARD_TYPE(Geom_Line)) {
616 Direc = Handle(Geom_Line)::DownCast(C)->Lin().Direction();
617 HCur = new GeomAdaptor_HCurve(C2);
620 else if (C2->DynamicType() == STANDARD_TYPE(Geom_Line)) {
621 Direc = Handle(Geom_Line)::DownCast(C2)->Lin().Direction();
622 HCur = new GeomAdaptor_HCurve(C);
625 badShape = TopoDS::Edge(ite.Key());
626 errStat = Draft_EdgeRecomputation;
627 break; // leave from while
629 Adaptor3d_SurfaceOfLinearExtrusion SLE(HCur,Direc);
630 switch(SLE.GetType()){
634 S2 = new Geom_Plane(SLE.Plane());
637 case GeomAbs_Cylinder :
639 S2 = new Geom_CylindricalSurface(SLE.Cylinder());
644 S2 = new Geom_SurfaceOfLinearExtrusion(HCur->ChangeCurve().
653 badShape = TopoDS::Edge(ite.Key());
654 errStat = Draft_EdgeRecomputation;
655 break; // leave from while
663 if (badShape.IsNull()) {
665 TopoDS_Face TheNewFace;
666 B.MakeFace(TheNewFace,S2,Precision::Confusion());
667 Einf.Add(TheNewFace);
668 Draft_FaceInfo FI(S2,Standard_False);
669 myFMap.Bind(TheNewFace,FI);
672 break; // leave from for
677 return (badShape.IsNull());
683 //=======================================================================
686 //=======================================================================
688 void Draft_Modification::Perform ()
690 if (!badShape.IsNull()) Standard_ConstructionError::Raise();
693 myComp = Standard_True;
698 // Calculate eventual faces
700 Draft_DataMapIteratorOfDataMapOfFaceFaceInfo itf(myFMap);
702 Draft_FaceInfo& Finf = myFMap(itf.Key());
703 if (Finf.NewGeometry() && Finf.Geometry().IsNull()) {
704 const TopoDS_Face& F1 = Finf.FirstFace();
705 const TopoDS_Face& F2 = Finf.SecondFace();
707 if (F1.IsNull() || F2.IsNull()) {
708 errStat = Draft_FaceRecomputation;
709 badShape = TopoDS::Face(itf.Key());
712 Handle(Geom_Surface) S1 = myFMap(F1).Geometry();
713 Handle(Geom_Surface) S2 = myFMap(F2).Geometry();
714 if (S1.IsNull() || S2.IsNull()) {
715 errStat = Draft_FaceRecomputation;
716 badShape = TopoDS::Face(itf.Key());
719 if (S1->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
720 S1 = Handle(Geom_RectangularTrimmedSurface)::
721 DownCast(S1)->BasisSurface();
723 if (S2->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
724 S2 = Handle(Geom_RectangularTrimmedSurface)::
725 DownCast(S2)->BasisSurface();
727 Handle(Geom_Plane) P1 = Handle(Geom_Plane)::DownCast(S1);
728 Handle(Geom_Plane) P2 = Handle(Geom_Plane)::DownCast(S2);
729 if (P1.IsNull() || P2.IsNull()) {
730 errStat = Draft_FaceRecomputation;
731 badShape = TopoDS::Face(itf.Key());
734 gp_Pln pp1 = P1->Pln();
735 gp_Pln pp2 = P2->Pln();
736 IntAna_QuadQuadGeo i2p(pp1,pp2,
737 Precision::Angular(),Precision::Confusion());
738 if (!i2p.IsDone() || i2p.TypeInter() != IntAna_Line) {
739 errStat = Draft_FaceRecomputation;
740 badShape = TopoDS::Face(itf.Key());
744 gp_Dir extrdir = i2p.Line(1).Direction();
746 // Preserve the same direction as the base face
747 Handle(Geom_Surface) RefSurf =
748 BRep_Tool::Surface(TopoDS::Face(itf.Key()));
749 if (RefSurf->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
751 Handle(Geom_RectangularTrimmedSurface)::DownCast(RefSurf)
756 if ( RefSurf->DynamicType() == STANDARD_TYPE(Geom_CylindricalSurface)) {
758 Handle(Geom_CylindricalSurface)::DownCast(RefSurf)
759 ->Cylinder().Position();
760 DirRef = AxeRef.Direction();
762 else if (RefSurf->DynamicType() ==
763 STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
765 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(RefSurf)
769 if (extrdir.Dot(DirRef) < 0.) extrdir.Reverse();
771 // it is possible to accelerate speed by storing the info during
772 // InternalAdd --> modification of FaceInfo to preserve the circle
774 Handle(Geom_Circle) CCir =
775 Handle(Geom_Circle)::DownCast(Finf.Curve());
776 Handle(Geom_Surface) NewS =
777 new Geom_SurfaceOfLinearExtrusion(CCir, extrdir);
779 Standard_Real umin, umax, vmin, vmax;
780 BRepTools::UVBounds(TopoDS::Face(itf.Key()),umin,umax,vmin,vmax);
781 if (!Precision::IsNegativeInfinite(vmin) &&
782 !Precision::IsPositiveInfinite(vmax)) {
783 Standard_Real deltav = 2.*(vmax-vmin);
784 vmin = vmin - deltav;
785 vmax = vmax + deltav;
794 NewS = new Geom_RectangularTrimmedSurface(NewS,0.,1.9*M_PI,vmin,vmax);
795 Finf.ChangeGeometry() = NewS;
800 // Calculate new edges.
802 Handle(Geom_Surface) S1,S2;
803 Handle(Geom_Curve) C, newC;
806 Draft_DataMapIteratorOfDataMapOfEdgeEdgeInfo ite(myEMap);
809 Draft_EdgeInfo& Einf = myEMap(ite.Key());
811 const TopoDS_Edge& theEdge = TopoDS::Edge(ite.Key());
813 C = BRep_Tool::Curve(theEdge,L,f,l);
814 C = Handle(Geom_Curve)::DownCast(C->Transformed(L.Transformation()));
816 if (Einf.NewGeometry() && Einf.Geometry().IsNull()) {
818 if (!Einf.IsTangent(ptfixe)) {
819 const TopoDS_Face& FirstFace = Einf.FirstFace();
820 const TopoDS_Face& SecondFace = Einf.SecondFace();
822 S1 = myFMap(FirstFace).Geometry();
823 S2 = myFMap(SecondFace).Geometry();
825 Standard_Integer detrompeur = 0;
827 // Return FirstVertex and the tangent at this point.
828 TopoDS_Vertex FV = TopExp::FirstVertex(theEdge);
829 TopoDS_Vertex LV = TopExp::LastVertex(theEdge);
830 Standard_Real pmin = 0.;
831 Standard_Real prmfv = BRep_Tool::Parameter(FV,ite.Key());
832 Standard_Real prmlv = BRep_Tool::Parameter(LV,ite.Key());
834 gp_Vec d1fv,d1lv, newd1;
835 C->D1(prmfv,pfv,d1fv);
836 C->D1(prmlv,plv,d1lv);
838 Standard_Real TolF1 = BRep_Tool::Tolerance (FirstFace);
839 Standard_Real TolF2 = BRep_Tool::Tolerance (SecondFace);
841 //Pass the tolerance of the face to project
842 GeomAPI_ProjectPointOnSurf proj1 (pfv, S1, TolF1);
843 GeomAPI_ProjectPointOnSurf proj2 (plv, S1, TolF1);
844 GeomAPI_ProjectPointOnSurf proj3 (pfv, S2, TolF2);
845 GeomAPI_ProjectPointOnSurf proj4 (plv, S2, TolF2);
847 if (proj1.IsDone () && proj2.IsDone ()) {
848 if(proj1.LowerDistance()<= Precision::Confusion() &&
849 proj2.LowerDistance()<= Precision::Confusion()) {
854 if (proj3.IsDone () && proj4.IsDone ()) {
855 if(proj3.LowerDistance() <= Precision::Confusion() &&
856 proj4.LowerDistance() <= Precision::Confusion()) {
863 Handle(Geom_Curve) TheNewCurve;
864 Standard_Boolean KPart = Standard_False;
866 if ( S1->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
867 S1 = Handle(Geom_RectangularTrimmedSurface)::
868 DownCast(S1)->BasisSurface();
870 if ( S2->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
871 S2 = Handle(Geom_RectangularTrimmedSurface)::
872 DownCast(S2)->BasisSurface();
875 Standard_Boolean PC1 = Standard_True; // KPart on S1
876 if (S1->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion) &&
877 S2->DynamicType() == STANDARD_TYPE(Geom_Plane) ) {
878 KPart = Standard_True;
879 Axis = Handle(Geom_Plane)::DownCast(S2)->Position();
880 TheNewCurve = Handle(Geom_SurfaceOfLinearExtrusion)::
881 DownCast(S1)->BasisCurve();
882 TheDirExtr = Handle(Geom_SurfaceOfLinearExtrusion)::
883 DownCast(S1)->Direction();
885 else if (S2->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion) &&
886 S1->DynamicType() == STANDARD_TYPE(Geom_Plane) ) {
887 KPart = Standard_True;
888 PC1 = Standard_False;
889 Axis = Handle(Geom_Plane)::DownCast(S1)->Position();
890 TheNewCurve = Handle(Geom_SurfaceOfLinearExtrusion)::
891 DownCast(S2)->BasisCurve();
892 TheDirExtr = Handle(Geom_SurfaceOfLinearExtrusion)::
893 DownCast(S2)->Direction();
895 Handle(Geom_Circle) aCirc ;
896 if ( KPart) { // very temporary on circles !!!
897 aCirc = Handle(Geom_Circle)::DownCast(TheNewCurve);
899 KPart = Standard_False;
902 gp_Dir AxofCirc = aCirc->Position().Direction();
903 if (AxofCirc.IsParallel(Axis.Direction(),Precision::Angular()))
904 KPart = Standard_True;
906 KPart = Standard_False;
910 Standard_Integer imin;
913 // direct calculation of NewC
914 Standard_Real aLocalReal =
915 gp_Vec(aCirc->Circ().Location(),Axis.Location()).
916 Dot(Axis.Direction());
917 Standard_Real Cos = TheDirExtr.Dot(Axis.Direction());
918 gp_Vec VV = ( aLocalReal / Cos) * TheDirExtr;
919 newC = Handle(Geom_Curve)::DownCast(TheNewCurve->Translated(VV));
920 // it is possible to calculate PCurve
921 Handle(Geom2d_Line) L2d
922 = new Geom2d_Line(gp_Pnt2d(0.,aLocalReal/Cos),
926 Einf.ChangeFirstPC() = L2d;
928 Einf.ChangeSecondPC() = L2d;
931 S1 = myFMap(Einf.FirstFace()).Geometry();
932 S2 = myFMap(Einf.SecondFace()).Geometry();
935 // PCurves are not calculated immediately for 2 reasons:
936 // 1 - If ProjLib should make an Approx, it is stupid to approximate the
937 // entire intersection curve.
938 // 2 - Additionally, if YaRev, there is a risk to not be SameRange.
939 i2s.Perform(S1,S2,Precision::Confusion(),
940 Standard_True,Standard_False,Standard_False);
942 if (!i2s.IsDone() || i2s.NbLines() <= 0) {
943 errStat = Draft_EdgeRecomputation;
944 badShape = TopoDS::Edge(ite.Key());
948 Standard_Real Dist2, Dist2Min = 0., Glob2Min = RealLast();
949 GeomAdaptor_Curve TheCurve;
951 Standard_Integer i,j; //,jmin;
953 if (i2s.Line(1)->DynamicType() != STANDARD_TYPE(Geom_BSplineCurve))
956 for (i=1; i<= i2s.NbLines(); i++) {
957 TheCurve.Load(i2s.Line(i));
958 Extrema_ExtPC myExtPC(pfv,TheCurve);
960 Standard_Real locpmin = 0.;
961 if (myExtPC.IsDone()) {
962 if(myExtPC.NbExt() >= 1) {
963 Dist2Min = myExtPC.SquareDistance(1);
964 locpmin = myExtPC.Point(1).Parameter();
966 if(myExtPC.NbExt() == 2 && Dist2Min > Precision::SquareConfusion()) {
967 //to avoid incorrectly choosing the image
968 //of the first vertex of the initial edge
969 Standard_Real d1_2 = myExtPC.SquareDistance(1);
970 Standard_Real d2_2 = myExtPC.SquareDistance(2);
971 if(d1_2 > 1.21*d2_2) {
972 Dist2Min = myExtPC.SquareDistance(2);
973 locpmin = myExtPC.Point(2).Parameter();
975 else if(d2_2 > 1.21*d1_2) {
976 Dist2Min = myExtPC.SquareDistance(1);
977 locpmin = myExtPC.Point(1).Parameter();
980 Standard_Real pfvpar = myExtPC.Point(1).Parameter();
981 Standard_Real plvpar = myExtPC.Point(2).Parameter();
984 gp_Pnt pfvprim, plvprim;
986 newC->D0(pfvpar,pfvprim);
987 newC->D0(plvpar,plvprim);
989 Handle(Geom_Surface) theSurf;
990 if(detrompeur == 1) {
991 if(S1->DynamicType() ==
992 STANDARD_TYPE(Geom_RectangularTrimmedSurface))
993 S1 = Handle(Geom_RectangularTrimmedSurface)::
994 DownCast(S1)->BasisSurface();
998 else if(detrompeur == 2) {
999 if(S2->DynamicType() ==
1000 STANDARD_TYPE(Geom_RectangularTrimmedSurface))
1001 S2 = Handle(Geom_RectangularTrimmedSurface)::
1002 DownCast(S2)->BasisSurface();
1005 if(detrompeur != 0 && detrompeur != 4) {
1006 Standard_Real ul = 0., vl = 0., uf = 0., vf = 0.;
1007 Standard_Real ufprim = 0., ulprim = 0., vfprim = 0., vlprim = 0.;
1009 if(theSurf->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
1010 gp_Pln pl = Handle(Geom_Plane)::DownCast(S2)->Pln();
1011 ElSLib::Parameters(pl, plv, ul, vl);
1012 ElSLib::Parameters(pl, pfv, uf, vf);
1013 ElSLib::Parameters(pl, plvprim, ulprim, vlprim);
1014 ElSLib::Parameters(pl, pfvprim, ufprim, vfprim);
1016 else if(theSurf->DynamicType() ==
1017 STANDARD_TYPE(Geom_CylindricalSurface)) {
1018 gp_Cylinder cy = Handle(Geom_CylindricalSurface)
1019 ::DownCast(S2)->Cylinder();
1020 ElSLib::Parameters(cy, plv, ul, vl);
1021 ElSLib::Parameters(cy, pfv, uf, vf);
1022 ElSLib::Parameters(cy, plvprim, ulprim, vlprim);
1023 ElSLib::Parameters(cy, pfvprim, ufprim, vfprim);
1025 else detrompeur = 4;
1027 if(detrompeur == 1 || detrompeur == 2) {
1028 gp_Vec2d v1((ul-ufprim), (vl-vfprim));
1029 gp_Vec2d norm((vf-vfprim), (ufprim-uf));
1030 gp_Vec2d v2((ulprim-ufprim), (vlprim-vfprim));
1031 if( (v1.Dot(norm))*(v2.Dot(norm)) < 0) {
1032 Dist2Min = myExtPC.SquareDistance(2);
1033 locpmin = myExtPC.Point(2).Parameter();
1039 if (myExtPC.NbExt() == 1 || myExtPC.NbExt() > 2 || detrompeur ==4) {
1040 Dist2Min = myExtPC.SquareDistance(1);
1041 locpmin = myExtPC.Point(1).Parameter();
1042 for (j=2; j<=myExtPC.NbExt(); j++) {
1043 Dist2 = myExtPC.SquareDistance(j);
1044 if (Dist2 < Dist2Min) {
1046 locpmin = myExtPC.Point(j).Parameter();
1050 else if(myExtPC.NbExt() < 1){
1051 Standard_Real dist1_2,dist2_2;
1053 myExtPC.TrimmedSquareDistances(dist1_2,dist2_2,p1b,p2b);
1054 if (dist1_2 < dist2_2) {
1056 locpmin = TheCurve.FirstParameter();
1060 locpmin = TheCurve.LastParameter();
1064 if (Dist2Min < Glob2Min) {
1065 Glob2Min = Dist2Min;
1072 errStat = Draft_EdgeRecomputation;
1073 badShape = TopoDS::Edge(ite.Key());
1077 newC = i2s.Line(imin);
1079 newC->D1(pmin,pfv,newd1);
1080 Standard_Boolean YaRev = d1fv.Dot(newd1) <0.;
1085 if (i2s.HasLineOnS1(imin)) {
1086 Einf.ChangeFirstPC() = i2s.LineOnS1(imin);
1088 Einf.ChangeFirstPC()->Reverse();
1091 if (i2s.HasLineOnS2(imin)) {
1092 Einf.ChangeSecondPC() = i2s.LineOnS2(imin);
1094 Einf.ChangeSecondPC()->Reverse();
1096 } // if (i2s.Line(1)->DynamicType() != STANDARD_TYPE(Geom_BSplineCurve))
1097 else // i2s.Line(1) is BSplineCurve
1099 //Find the first curve to glue
1100 TColGeom_SequenceOfCurve Candidates;
1101 if (S1->DynamicType() == STANDARD_TYPE(Geom_CylindricalSurface) ||
1102 S1->DynamicType() == STANDARD_TYPE(Geom_ConicalSurface))
1104 for (i = 1; i <= i2s.NbLines(); i++)
1106 Handle( Geom_Curve ) aCurve = i2s.Line(i);
1107 gp_Pnt Pnt = aCurve->Value( aCurve->FirstParameter() );
1108 GeomAPI_ProjectPointOnSurf projector( Pnt, S1, Precision::Confusion() );
1110 projector.LowerDistanceParameters( U, V );
1111 if (Abs(U) <= Precision::Confusion() || Abs(U-2.*M_PI) <= Precision::Confusion())
1112 Candidates.Append( aCurve );
1115 Pnt = aCurve->Value( aCurve->LastParameter() );
1116 projector.Init( Pnt, S1, Precision::Confusion() );
1117 projector.LowerDistanceParameters( U, V );
1118 if (Abs(U) <= Precision::Confusion() || Abs(U-2.*M_PI) <= Precision::Confusion())
1121 Candidates.Append( aCurve );
1126 if(Candidates.Length() == 0)
1128 // errStat = Draft_EdgeRecomputation;
1129 // badShape = TopoDS::Edge(ite.Key());
1131 for (i = 1; i <= i2s.NbLines(); i++)
1132 Candidates.Append( i2s.Line(i) );
1137 for (i = 1; i <= i2s.NbLines(); i++)
1138 Candidates.Append( i2s.Line(i) );
1141 Handle( Geom_Curve ) FirstCurve;
1142 if (Candidates.Length() > 1)
1144 Dist2Min = RealLast();
1145 for (i = 1; i <= Candidates.Length(); i++)
1147 Handle( Geom_Curve ) aCurve = Candidates(i);
1148 gp_Pnt Pnt = aCurve->Value( aCurve->FirstParameter() );
1149 Dist2 = Pnt.SquareDistance( pfv );
1150 if (Dist2 < Dist2Min)
1153 FirstCurve = aCurve;
1158 FirstCurve = Candidates(1);
1161 TColGeom_SequenceOfCurve Curves;
1162 for (i = 1; i <= i2s.NbLines(); i++)
1163 if (FirstCurve != i2s.Line(i))
1164 Curves.Append( i2s.Line(i) );
1166 TColGeom_SequenceOfCurve ToGlue;
1167 gp_Pnt EndPoint = FirstCurve->Value( FirstCurve->LastParameter() );
1168 Standard_Boolean added = Standard_True;
1171 added = Standard_False;
1172 for (i = 1; i <= Curves.Length(); i++)
1174 Handle( Geom_Curve ) aCurve = Curves(i);
1175 gp_Pnt pfirst, plast;
1176 pfirst = aCurve->Value( aCurve->FirstParameter() );
1177 plast = aCurve->Value( aCurve->LastParameter() );
1178 if (pfirst.Distance( EndPoint ) <= Precision::Confusion())
1180 ToGlue.Append( aCurve );
1183 added = Standard_True;
1186 if (plast.Distance( EndPoint ) <= Precision::Confusion())
1189 ToGlue.Append( aCurve );
1192 added = Standard_True;
1198 if (FirstCurve.IsNull()) {
1199 errStat = Draft_EdgeRecomputation;
1200 badShape = TopoDS::Edge(ite.Key());
1204 GeomConvert_CompCurveToBSplineCurve Concat( Handle(Geom_BSplineCurve)::DownCast(FirstCurve) );
1205 for (i = 1; i <= ToGlue.Length(); i++)
1206 Concat.Add( Handle(Geom_BSplineCurve)::DownCast(ToGlue(i)), Precision::Confusion(), Standard_True );
1208 newC = Concat.BSplineCurve();
1210 TheCurve.Load( newC );
1211 Extrema_ExtPC myExtPC( pfv, TheCurve );
1212 Dist2Min = RealLast();
1213 for (i = 1; i <= myExtPC.NbExt(); i++)
1215 Dist2 = myExtPC.SquareDistance(i);
1216 if (Dist2 < Dist2Min)
1219 pmin = myExtPC.Point(i).Parameter();
1223 newC->D1(pmin,pfv,newd1);
1224 Standard_Boolean YaRev = d1fv.Dot(newd1) < 0.;
1229 if (i2s.HasLineOnS1(imin)) {
1230 Einf.ChangeFirstPC() = i2s.LineOnS1(imin);
1232 Einf.ChangeFirstPC()->Reverse();
1235 if (i2s.HasLineOnS2(imin)) {
1236 Einf.ChangeSecondPC() = i2s.LineOnS2(imin);
1238 Einf.ChangeSecondPC()->Reverse();
1241 } // else: i2s.NbLines() > 2 && S1 is Cylinder or Cone
1243 Einf.Tolerance(Max(Einf.Tolerance(), i2s.TolReached3d()));
1246 else { // case of tangency
1247 const TopoDS_Face& F1 = Einf.FirstFace();
1248 const TopoDS_Face& F2 = Einf.SecondFace();
1250 Handle(Geom_Surface) aLocalS1 = myFMap(F1).Geometry();
1251 Handle(Geom_Surface) aLocalS2 = myFMap(F2).Geometry();
1252 if (aLocalS1.IsNull() || aLocalS2.IsNull()) {
1253 errStat = Draft_EdgeRecomputation;
1254 badShape = TopoDS::Edge(ite.Key());
1257 if (aLocalS1->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1258 aLocalS1 = Handle(Geom_RectangularTrimmedSurface)::
1259 DownCast(aLocalS1)->BasisSurface();
1261 if (aLocalS2->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1262 aLocalS2 = Handle(Geom_RectangularTrimmedSurface)::
1263 DownCast(aLocalS2)->BasisSurface();
1267 //Standard_Boolean dirfound = Standard_False;
1268 if (aLocalS1->DynamicType() == STANDARD_TYPE(Geom_CylindricalSurface)) {
1270 Handle(Geom_CylindricalSurface)::DownCast(aLocalS1)->Cylinder();
1271 dirextr = cyl.Axis().Direction();
1272 //dirfound = Standard_True;
1276 else if (aLocalS1->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
1277 dirextr = Handle(Geom_SurfaceOfLinearExtrusion)::
1278 DownCast(aLocalS1)->Direction();
1279 //dirfound = Standard_True;
1282 // Here it is possible to calculate PCurve.
1283 Handle(Geom_SurfaceOfLinearExtrusion) SEL =
1284 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(aLocalS1);
1285 Handle(Geom_Circle) GCir =
1286 Handle(Geom_Circle)::DownCast(SEL->BasisCurve());
1287 if ( !GCir.IsNull()) {
1288 Standard_Real U = ElCLib::Parameter(GCir->Circ(),ptfixe);
1289 Handle(Geom2d_Line) PC1 =
1290 new Geom2d_Line(gp_Pnt2d(U,0.),gp::DY2d());
1291 Einf.ChangeFirstPC() = PC1;
1295 else if (aLocalS2->DynamicType() == STANDARD_TYPE(Geom_CylindricalSurface)) {
1297 Handle(Geom_CylindricalSurface)::DownCast(aLocalS2)->Cylinder();
1298 dirextr = cyl.Axis().Direction();
1299 // dirfound = Standard_True;
1303 else if (aLocalS2->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
1304 dirextr = Handle(Geom_SurfaceOfLinearExtrusion)::
1305 DownCast(aLocalS2)->Direction();
1306 // dirfound = Standard_True;
1309 // Here it is possible to calculate PCurve.
1310 Handle(Geom_SurfaceOfLinearExtrusion) SEL =
1311 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(aLocalS2);
1312 Handle(Geom_Circle) GCir =
1313 Handle(Geom_Circle)::DownCast(SEL->BasisCurve());
1314 if ( !GCir.IsNull()) {
1315 Standard_Real U = ElCLib::Parameter(GCir->Circ(),ptfixe);
1316 Handle(Geom2d_Line) PC2 =
1317 new Geom2d_Line(gp_Pnt2d(U,0.),gp::DY2d());
1318 Einf.ChangeSecondPC() = PC2;
1321 newC = new Geom_Line(ptfixe,dirextr);
1326 newC->D1(0.,pfv,newd1);
1327 Standard_Boolean YaRev = d1fv.Dot(newd1) <0.;
1330 if(!Einf.FirstPC().IsNull()) {
1331 Einf.ChangeFirstPC()->Reverse();
1333 if(!Einf.SecondPC().IsNull()) {
1334 Einf.ChangeSecondPC()->Reverse();
1339 Handle(Geom_TrimmedCurve) T = Handle(Geom_TrimmedCurve)::DownCast(newC);
1340 if (!T.IsNull()) newC = T->BasisCurve();
1341 Einf.ChangeGeometry() = newC;
1343 else if (!Einf.NewGeometry()){
1344 // set existing curve 3D
1345 Handle(Geom_TrimmedCurve) T = Handle(Geom_TrimmedCurve)::DownCast(C);
1346 if (!T.IsNull()) C = T->BasisCurve();
1347 Einf.ChangeGeometry() = C;
1352 // Calculate new vertices.
1354 Draft_DataMapIteratorOfDataMapOfVertexVertexInfo itv(myVMap);
1356 Handle(GeomAdaptor_HCurve) HAC = new GeomAdaptor_HCurve;
1357 Handle(GeomAdaptor_HSurface) HAS = new GeomAdaptor_HSurface;
1359 while (itv.More()) {
1360 GeomAdaptor_Curve AC;
1361 GeomAdaptor_Surface AS;
1363 Draft_VertexInfo& Vinf = myVMap(itv.Key());
1364 if (!Choose(myFMap,myEMap,itv.Key(),Vinf,AC,AS)) {
1366 // no concerted edge => alignment of two consecutive edges.
1368 Vinf.ChangeGeometry() = pvt;
1369 Vinf.InitEdgeIterator();
1370 if (Vinf.MoreEdge()) {
1371 const TopoDS_Edge& Edg1 = Vinf.Edge();
1372 //const Draft_EdgeInfo& Einf1 = myEMap(Edg1);
1373 Draft_EdgeInfo& Einf1 = myEMap(Edg1);
1374 gp_Pnt vtori = BRep_Tool::Pnt(itv.Key());
1375 //Einf1.Geometry()->D0(Vinf.Parameter(Edg1), pvt);
1376 GeomAPI_ProjectPointOnCurve Projector( vtori, Einf1.Geometry() ); //patch
1377 pvt = Projector.NearestPoint();
1380 static Standard_Integer VertexRecomp = 1;
1381 if (VertexRecomp!=0) {
1382 cout << "pori :" << vtori.X() << " " << vtori.Y() << " " << vtori.Z() << endl;
1383 cout << " Edg 1 :" << Vinf.Parameter(Edg1) << endl;
1384 cout << "pvt :" << pvt.X() << " " << pvt.Y() << " " << pvt.Z() << endl;
1388 Standard_Real dion=pvt.SquareDistance(vtori);
1390 if (Vinf.MoreEdge()) {
1391 const TopoDS_Edge& Edg2 = Vinf.Edge();
1392 //const Draft_EdgeInfo& Einf2 = myEMap(Edg2);
1393 Draft_EdgeInfo& Einf2 = myEMap(Edg2);
1396 Einf2.Geometry()->D0(Vinf.Parameter(Edg2), opvt);
1399 if (VertexRecomp!=0) {
1400 cout << " Edg 2 :" << Vinf.Parameter(Vinf.Edge()) << endl;
1401 cout << "opvt " << opvt.X() << " " << opvt.Y() << " " << opvt.Z() << endl;
1405 if (opvt.SquareDistance(vtori) < dion) {
1408 //Vinf.ChangeParameter(Edg2) = Parameter(Einf2.Geometry(), pvt);
1409 Standard_Integer done;
1410 Standard_Real param = Parameter(Einf2.Geometry(), pvt, done);
1413 S1 = myFMap(Einf2.FirstFace()).Geometry();
1414 S2 = myFMap(Einf2.SecondFace()).Geometry();
1415 Vinf.ChangeParameter(Edg2) = SmartParameter( Einf2, BRep_Tool::Tolerance(Edg2), pvt, done, S1, S2 );
1418 Vinf.ChangeParameter(Edg2) = param;
1421 Vinf.ChangeGeometry() = pvt;
1422 //Vinf.ChangeParameter(Edg1) = Parameter(Einf1.Geometry(), pvt);
1423 Standard_Integer done;
1424 Standard_Real param = Parameter(Einf1.Geometry(), pvt, done);
1427 S1 = myFMap(Einf1.FirstFace()).Geometry();
1428 S2 = myFMap(Einf1.SecondFace()).Geometry();
1429 Vinf.ChangeParameter(Edg1) = SmartParameter( Einf1, BRep_Tool::Tolerance(Edg1), pvt, done, S1, S2 );
1432 Vinf.ChangeParameter(Edg1) = param;
1438 errStat = Draft_VertexRecomputation;
1439 badShape = TopoDS::Vertex(itv.Key());
1443 IntCurveSurface_HInter myintcs;
1446 myintcs.Perform(HAC,HAS);
1448 if (!myintcs.IsDone()) {
1449 errStat = Draft_VertexRecomputation;
1450 badShape = TopoDS::Vertex(itv.Key());
1454 gp_Pnt vtori = BRep_Tool::Pnt(itv.Key());
1457 Standard_Integer nbsol = myintcs.NbPoints();
1460 Extrema_ExtCS extr( AC, AS, Precision::PConfusion(), Precision::PConfusion() );
1462 if(!extr.IsDone() || extr.NbExt() == 0) {
1463 errStat = Draft_VertexRecomputation;
1464 badShape = TopoDS::Vertex(itv.Key());
1469 Standard_Real disref = RealLast();
1470 Standard_Integer iref = 0;
1473 for (Standard_Integer i = 1; i <= extr.NbExt(); i++)
1475 extr.Points( i, Pc, Ps );
1476 Standard_Real distemp = Pc.Value().SquareDistance(vtori);
1477 if ( distemp < disref)
1483 extr.Points( iref, Pc, Ps );
1488 Standard_Real disref = RealLast();
1489 Standard_Integer iref = 0;
1490 for (Standard_Integer i = 1; i <= nbsol; i++)
1492 Standard_Real distemp = myintcs.Point(i).Pnt().SquareDistance(vtori);
1493 if ( distemp < disref)
1499 pvt = myintcs.Point(iref).Pnt();
1502 Vinf.ChangeGeometry() = pvt;
1504 for (Vinf.InitEdgeIterator();Vinf.MoreEdge(); Vinf.NextEdge()) {
1505 const TopoDS_Edge& Edg = Vinf.Edge();
1506 //const Draft_EdgeInfo& Einf = myEMap(Edg);
1507 Draft_EdgeInfo& Einf = myEMap(Edg);
1508 //Vinf.ChangeParameter(Edg) = Parameter(Einf.Geometry(),pvt);
1509 Standard_Integer done;
1510 Standard_Real param = Parameter(Einf.Geometry(), pvt, done);
1513 S1 = myFMap(Einf.FirstFace()).Geometry();
1514 S2 = myFMap(Einf.SecondFace()).Geometry();
1515 Vinf.ChangeParameter(Edg) = SmartParameter( Einf, BRep_Tool::Tolerance(Edg), pvt, done, S1, S2 );
1518 Vinf.ChangeParameter(Edg) = param;
1524 // small loop of validation/protection
1526 for (Draft_DataMapIteratorOfDataMapOfEdgeEdgeInfo ite(myEMap);
1527 ite.More(); ite.Next()) {
1528 const TopoDS_Edge& edg = TopoDS::Edge(ite.Key());
1530 TopoDS_Vertex Vf,Vl;
1531 TopExp::Vertices(edg,Vf,Vl);
1532 if (edg.Orientation() == TopAbs_REVERSED) {
1536 Standard_Real pf,pl,tolerance;
1537 if (!NewParameter(Vf,edg,pf,tolerance)) {
1538 pf = BRep_Tool::Parameter(Vf,edg);
1540 if (!NewParameter(Vl,edg,pl,tolerance)) {
1541 pl = BRep_Tool::Parameter(Vl,edg);
1544 // const Handle(Geom_Curve) gc=ite.Value().Geometry();
1545 // if (!gc.IsNull()) {
1546 // pl = gc->LastParameter();
1547 // pf = gc->FirstParameter();
1549 Handle( Geom_Curve ) theCurve = myEMap(edg).Geometry();
1550 if (theCurve->IsClosed())
1553 Standard_Real FirstPar = theCurve->FirstParameter(), LastPar = theCurve->LastParameter();
1554 Standard_Real pconf = Precision::PConfusion();
1555 if (Abs( pf - LastPar ) <= pconf)
1557 else if (Abs( pl - FirstPar ) <= pconf)
1561 pl += (LastPar-FirstPar);
1566 errStat = Draft_EdgeRecomputation;
1567 badShape = TopoDS::Edge(ite.Key());
1571 if (myVMap.IsBound( Vf ))
1572 myVMap(Vf).ChangeParameter(edg) = pf;
1573 if (myVMap.IsBound( Vl ))
1574 myVMap(Vl).ChangeParameter(edg) = pl;
1580 //=======================================================================
1581 //function : NewSurface
1583 //=======================================================================
1585 Handle(Geom_Surface) Draft_Modification::NewSurface
1586 (const Handle(Geom_Surface)& S,
1587 const TopAbs_Orientation Oris,
1588 const gp_Dir& Direction,
1589 const Standard_Real Angle,
1590 const gp_Pln& NeutralPlane)
1592 Handle(Geom_Surface) NewS;
1594 Handle(Standard_Type) TypeS = S->DynamicType();
1596 if (TypeS == STANDARD_TYPE(Geom_Plane)) {
1597 gp_Pln Pl = Handle(Geom_Plane)::DownCast(S)->Pln();
1599 Standard_Real Theta;
1600 if (FindRotation(Pl,Oris,Direction,Angle,NeutralPlane,Axe,Theta)) {
1601 if ( Abs(Theta) > Precision::Angular()) {
1602 NewS = Handle(Geom_Surface)::DownCast(S->Rotated(Axe,Theta));
1609 else if (TypeS == STANDARD_TYPE(Geom_CylindricalSurface)) {
1610 Standard_Real testdir = Direction.Dot(NeutralPlane.Axis().Direction());
1611 if (Abs(testdir) <= 1.-Precision::Angular()) {
1613 cout << "NewSurfaceCyl:Draft_Direction_and_Neutral_Perpendicular" << endl;
1617 gp_Cylinder Cy = Handle(Geom_CylindricalSurface)::DownCast(S)->Cylinder();
1618 testdir = Direction.Dot(Cy.Axis().Direction());
1619 if (Abs(testdir) <= 1.-Precision::Angular()) {
1621 cout << "NewSurfaceCyl:Draft_Direction_and_Cylinder_Perpendicular" << endl;
1625 if (Abs(Angle) > Precision::Angular())
1627 IntAna_QuadQuadGeo i2s;
1628 i2s.Perform(NeutralPlane,Cy,Precision::Angular(),Precision::Confusion());
1629 Standard_Boolean isIntDone = i2s.IsDone();
1631 if(i2s.TypeInter() == IntAna_Ellipse)
1633 const gp_Elips anEl = i2s.Ellipse(1);
1634 const Standard_Real aMajorR = anEl.MajorRadius();
1635 const Standard_Real aMinorR = anEl.MinorRadius();
1636 isIntDone = (aMajorR < 100000.0 * aMinorR);
1639 if (!isIntDone || i2s.TypeInter() != IntAna_Circle) {
1641 cout << "NewSurfaceCyl:Draft_Intersection_Neutral_Cylinder_NotDone" << endl;
1645 gp_Ax3 axcone = Cy.Position();
1646 // Pb : Where is the material???
1647 Standard_Real alpha = Angle;
1648 Standard_Boolean direct(axcone.Direct());
1649 if ((direct && Oris == TopAbs_REVERSED) ||
1650 (!direct && Oris == TopAbs_FORWARD)) {
1654 gp_Pnt Center = i2s.Circle(1).Location();
1658 Standard_Real Z = ElCLib::LineParameter(Cy.Axis(),Center);
1659 Standard_Real Rad = Cy.Radius()+Z*Tan(alpha);
1666 gp_Cone co(axcone,alpha,Rad);
1667 NewS = new Geom_ConicalSurface(co);
1673 else if (TypeS == STANDARD_TYPE(Geom_ConicalSurface)) {
1675 Standard_Real testdir = Direction.Dot(NeutralPlane.Axis().Direction());
1676 if (Abs(testdir) <= 1.-Precision::Angular()) {
1678 cout << "NewSurfaceCone:Draft_Direction_and_Neutral_Perpendicular" << endl;
1683 gp_Cone Co1 = Handle(Geom_ConicalSurface)::DownCast(S)->Cone();
1685 testdir = Direction.Dot(Co1.Axis().Direction());
1686 if (Abs(testdir) <= 1.-Precision::Angular()) {
1688 cout << "NewSurfaceCone:Draft_Direction_and_Cone_Perpendicular" << endl;
1694 IntAna_QuadQuadGeo i2s;
1695 i2s.Perform(NeutralPlane,Co1,Precision::Angular(),Precision::Confusion());
1696 if (!i2s.IsDone() || i2s.TypeInter() != IntAna_Circle) {
1698 cout << "NewSurfaceCone:Draft_Intersection_Neutral_Conical_NotDone" << endl;
1702 gp_Ax3 axcone = Co1.Position();
1703 // Pb : Where is the material???
1704 Standard_Real alpha = Angle;
1705 Standard_Boolean direct(axcone.Direct());
1706 if ((direct && Oris == TopAbs_REVERSED) ||
1707 (!direct && Oris == TopAbs_FORWARD)) {
1711 gp_Pnt Center = i2s.Circle(1).Location();
1712 if (Abs(Angle) > Precision::Angular()) {
1716 Standard_Real Z = ElCLib::LineParameter(Co1.Axis(),Center);
1717 Standard_Real Rad = i2s.Circle(1).Radius()+Z*Tan(alpha);
1724 if (Abs(alpha-Co1.SemiAngle()) < Precision::Angular()) {
1728 gp_Cone co(axcone,alpha,Rad);
1729 NewS = new Geom_ConicalSurface(co);
1734 Geom_CylindricalSurface(gp_Cylinder(axcone,i2s.Circle(1).Radius()));
1739 cout << "NewSurface:Draft_SurfNotYetImplemented" << endl;
1746 //=======================================================================
1747 //function : NewCurve
1749 //=======================================================================
1751 Handle(Geom_Curve) Draft_Modification::NewCurve
1752 (const Handle(Geom_Curve)& C,
1753 const Handle(Geom_Surface)& S,
1754 const TopAbs_Orientation Oris,
1755 const gp_Dir& Direction,
1756 const Standard_Real Angle,
1757 const gp_Pln& NeutralPlane,
1758 const Standard_Boolean )
1761 Handle(Geom_Curve) NewC;
1763 Handle(Standard_Type) TypeS = S->DynamicType();
1765 if (TypeS == STANDARD_TYPE(Geom_Plane)) {
1766 gp_Pln Pl = Handle(Geom_Plane)::DownCast(S)->Pln();
1768 Standard_Real Theta;
1769 if (FindRotation(Pl,Oris,Direction,Angle,NeutralPlane,Axe,Theta)) {
1770 if ( Abs(Theta) > Precision::Angular()) {
1771 NewC = Handle(Geom_Curve)::DownCast(C->Rotated(Axe,Theta));
1781 if (C->DynamicType() != STANDARD_TYPE(Geom_Line)) {
1786 gp_Lin lin = Handle(Geom_Line)::DownCast(C)->Lin();
1787 // Standard_Real testdir = Direction.Dot(lin.Direction());
1788 // if (Abs(testdir) <= 1.-Precision::Angular()) {
1792 if (TypeS == STANDARD_TYPE(Geom_CylindricalSurface)) {
1796 gp_Cylinder Cy = Handle(Geom_CylindricalSurface)::DownCast(S)->Cylinder();
1797 ElSLib::Parameters(Cy,lin.Location(),U,V);
1798 ElSLib::D1(U,V,Cy,pbid,d1u,d1v);
1799 Norm = d1u.Crossed(d1v);
1801 else if (TypeS == STANDARD_TYPE(Geom_ConicalSurface)) {
1805 gp_Cone Co = Handle(Geom_ConicalSurface)::DownCast(S)->Cone();
1806 ElSLib::Parameters(Co,lin.Location(),U,V);
1807 ElSLib::D1(U,V,Co,pbid,d1u,d1v);
1808 Norm = d1u.Crossed(d1v);
1811 IntAna_IntConicQuad ilipl(lin,NeutralPlane,Precision::Angular());
1812 if (ilipl.IsDone() && ilipl.NbPoints() != 0){
1813 if (Oris == TopAbs_REVERSED) {
1816 gp_Ax1 axrot(ilipl.Point(1), Norm.Crossed(Direction));
1817 gp_Lin lires = gp_Lin(gp_Ax1(ilipl.Point(1),Direction)).
1818 Rotated(axrot,Angle);
1819 if (lires.Direction().Dot(lin.Direction()) < 0.) {
1822 NewC = new Geom_Line(lires);
1828 //=======================================================================
1831 //=======================================================================
1833 static Standard_Boolean Choose(const Draft_DataMapOfFaceFaceInfo& theFMap,
1834 Draft_DataMapOfEdgeEdgeInfo& theEMap,
1835 const TopoDS_Vertex& Vtx,
1836 Draft_VertexInfo& Vinf,
1837 GeomAdaptor_Curve& AC,
1838 GeomAdaptor_Surface& AS)
1841 Vinf.InitEdgeIterator();
1843 // Find a regular edge with null SecondFace
1844 while (Vinf.MoreEdge()) {
1845 const TopoDS_Edge& E1 = Vinf.Edge();
1846 const Draft_EdgeInfo& Einf1 = theEMap(E1);
1847 if (Einf1.SecondFace().IsNull()) {
1851 GeomAbs_Shape te = BRep_Tool::Continuity(E1,Einf1.FirstFace(),
1852 Einf1.SecondFace());
1853 if (te >= GeomAbs_G1) {
1859 if (!Vinf.MoreEdge()) { // take the first edge
1860 Vinf.InitEdgeIterator();
1863 const TopoDS_Edge& Eref = Vinf.Edge();
1864 //const Draft_EdgeInfo& Einf = theEMap(Eref);
1865 Draft_EdgeInfo& Einf = theEMap(Eref);
1867 AC.Load(Einf.Geometry());
1869 Standard_Real f,l,prm;
1870 TopLoc_Location Loc;
1871 Handle(Geom_Curve) C = BRep_Tool::Curve(Eref,Loc,f,l);
1872 C = Handle(Geom_Curve)::DownCast(C->Transformed(Loc.Transformation()));
1874 //prm = Parameter(C,BRep_Tool::Pnt(Vtx));
1875 Standard_Integer done;
1876 Standard_Real param = Parameter( C, BRep_Tool::Pnt(Vtx), done );
1879 Handle( Geom_Surface ) S1 = theFMap(Einf.FirstFace()).Geometry();
1880 Handle( Geom_Surface ) S2 = theFMap(Einf.SecondFace()).Geometry();
1881 prm = SmartParameter( Einf, BRep_Tool::Tolerance(Eref), BRep_Tool::Pnt(Vtx), done, S1, S2 );
1885 C->D1(prm,ptbid,tgref);
1888 Vinf.InitEdgeIterator();
1889 while (Vinf.MoreEdge()) {
1890 // Find a non tangent edge
1891 const TopoDS_Edge& Edg = Vinf.Edge();
1892 if (!Edg.IsSame(Eref)) {
1893 //const Draft_EdgeInfo& Einfo = theEMap(Edg);
1894 Draft_EdgeInfo& Einfo = theEMap(Edg);
1895 if (!Einfo.SecondFace().IsNull() &&
1896 BRep_Tool::Continuity(Edg,Einfo.FirstFace(),Einfo.SecondFace())
1898 C = BRep_Tool::Curve(Edg,Loc,f,l);
1899 C = Handle(Geom_Curve)::DownCast(C->Transformed(Loc.Transformation()));
1900 //prm = Parameter(C,BRep_Tool::Pnt(Vtx));
1901 Standard_Integer anewdone;
1902 Standard_Real anewparam = Parameter( C, BRep_Tool::Pnt(Vtx), anewdone );
1905 Handle( Geom_Surface ) S1 = theFMap(Einfo.FirstFace()).Geometry();
1906 Handle( Geom_Surface ) S2 = theFMap(Einfo.SecondFace()).Geometry();
1907 prm = SmartParameter( Einfo, BRep_Tool::Tolerance(Edg), BRep_Tool::Pnt(Vtx), anewdone, S1, S2 );
1912 C->D1(prm,ptbid,tg);
1913 if (tg.CrossMagnitude(tgref) > Precision::Confusion()) {
1920 if (!Vinf.MoreEdge()) {
1921 return Standard_False;
1924 const Draft_EdgeInfo& Einf2 = theEMap(Vinf.Edge());
1925 if (!Einf.SecondFace().IsNull()) {
1927 if (Einf2.FirstFace().IsSame(Einf.FirstFace()) ||
1928 Einf2.FirstFace().IsSame(Einf.SecondFace())) {
1929 AS.Load(theFMap(Einf2.SecondFace()).Geometry());
1932 AS.Load(theFMap(Einf2.FirstFace()).Geometry());
1936 if (Einf2.FirstFace().IsSame(Einf.FirstFace())) {
1937 AS.Load(theFMap(Einf2.SecondFace()).Geometry());
1940 AS.Load(theFMap(Einf2.FirstFace()).Geometry());
1943 return Standard_True;
1947 //=======================================================================
1948 //function : Parameter
1950 //=======================================================================
1952 static Standard_Real Parameter(const Handle(Geom_Curve)& C,
1954 Standard_Integer& done)
1957 Handle(Geom_Curve) cbase = C;
1958 Handle(Standard_Type) ctyp = C->DynamicType();
1959 if (ctyp == STANDARD_TYPE(Geom_TrimmedCurve)) {
1960 cbase = Handle(Geom_TrimmedCurve)::DownCast(C)->BasisCurve();
1961 ctyp = cbase->DynamicType();
1963 Standard_Real param;
1964 if (ctyp == STANDARD_TYPE(Geom_Line)) {
1965 param = ElCLib::Parameter(Handle(Geom_Line)::DownCast(cbase)->Lin(),P);
1967 else if (ctyp == STANDARD_TYPE(Geom_Circle)) {
1968 param = ElCLib::Parameter(Handle(Geom_Circle)::DownCast(cbase)->Circ(),P);
1969 if (Abs(2.*M_PI-param) <=Epsilon(2.*M_PI)) {
1973 else if (ctyp == STANDARD_TYPE(Geom_Ellipse)) {
1974 param = ElCLib::Parameter(Handle(Geom_Ellipse)::DownCast(cbase)->Elips(),P);
1975 if (Abs(2.*M_PI-param) <=Epsilon(2.*M_PI)) {
1979 else if (ctyp == STANDARD_TYPE(Geom_Parabola)) {
1980 param = ElCLib::Parameter(Handle(Geom_Parabola)::DownCast(cbase)->Parab(),P);
1982 else if (ctyp == STANDARD_TYPE(Geom_Hyperbola)) {
1983 param = ElCLib::Parameter(Handle(Geom_Hyperbola)::DownCast(cbase)->Hypr(),P);
1986 GeomAdaptor_Curve TheCurve(C);
1987 Extrema_ExtPC myExtPC(P,TheCurve);
1988 if (!myExtPC.IsDone()) {
1989 Standard_Failure::Raise();
1991 if (myExtPC.NbExt() >= 1) {
1992 Standard_Real Dist2, Dist2Min = myExtPC.SquareDistance(1);
1993 Standard_Integer j, jmin = 1;
1994 for (j = 2; j <= myExtPC.NbExt(); j++) {
1995 Dist2 = myExtPC.SquareDistance(j);
1996 if (Dist2 < Dist2Min) {
2001 param = myExtPC.Point(jmin).Parameter();
2004 Standard_Real dist1_2,dist2_2;
2006 myExtPC.TrimmedSquareDistances(dist1_2,dist2_2,p1b,p2b);
2007 if (dist1_2 < dist2_2) {
2009 param = TheCurve.FirstParameter();
2013 param = TheCurve.LastParameter();
2017 if (cbase->IsPeriodic()) {
2018 Standard_Real Per = cbase->Period();
2019 Standard_Real Tolp = Precision::Parametric(Precision::Confusion());
2020 if (Abs(Per-param) <= Tolp) {
2028 //=======================================================================
2029 //function : SmartParameter
2031 //=======================================================================
2033 static Standard_Real SmartParameter(Draft_EdgeInfo& Einf,
2034 const Standard_Real EdgeTol,
2036 const Standard_Integer sign,
2037 const Handle(Geom_Surface)& S1,
2038 const Handle(Geom_Surface)& S2)
2040 Handle( Geom2d_Curve ) NewC2d;
2041 Standard_Real Tol = Precision::Confusion();
2042 Standard_Real Etol = EdgeTol;
2044 Handle( Geom2d_Curve ) pcu1 = Einf.FirstPC();
2045 Handle( Geom2d_Curve ) pcu2 = Einf.SecondPC();
2049 Handle( Geom_Curve ) theCurve = Einf.Geometry();
2050 pcu1 = GeomProjLib::Curve2d( theCurve, theCurve->FirstParameter(), theCurve->LastParameter(), S1, Etol );
2051 Einf.ChangeFirstPC() = pcu1;
2055 Handle( Geom_Curve ) theCurve = Einf.Geometry();
2056 pcu2 = GeomProjLib::Curve2d( theCurve, theCurve->FirstParameter(), theCurve->LastParameter(), S2, Etol );
2057 Einf.ChangeSecondPC() = pcu2;
2060 GeomAPI_ProjectPointOnSurf Projector( Pnt, S1 );
2062 Projector.LowerDistanceParameters( U, V );
2064 NewC2d = Einf.FirstPC();
2065 if (NewC2d->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve))
2066 NewC2d = (Handle(Geom2d_TrimmedCurve)::DownCast(NewC2d))->BasisCurve();
2068 gp_Pnt2d P2d( U, V );
2069 Geom2dAPI_ProjectPointOnCurve Projector2d( P2d, NewC2d );
2070 if (Projector2d.NbPoints() == 0 || Projector2d.LowerDistance() > Tol)
2072 Handle( Geom2d_BSplineCurve ) BCurve;
2073 if (NewC2d->DynamicType() != STANDARD_TYPE(Geom2d_BSplineCurve))
2074 BCurve = Geom2dConvert::CurveToBSplineCurve( NewC2d );
2076 BCurve = Handle( Geom2d_BSplineCurve )::DownCast( NewC2d );
2079 TColgp_Array1OfPnt2d PntArray( 1, 2 );
2081 PntArray(2) = BCurve->Pole(1);
2082 Handle( Geom2d_BezierCurve ) Patch = new Geom2d_BezierCurve( PntArray );
2083 Geom2dConvert_CompCurveToBSplineCurve Concat( BCurve, Convert_QuasiAngular );
2084 Concat.Add( Patch, Tol, Standard_False );
2085 BCurve = Concat.BSplineCurve();
2089 TColgp_Array1OfPnt2d PntArray( 1, 2 );
2090 PntArray(1) = BCurve->Pole( BCurve->NbPoles() );
2092 Handle( Geom2d_BezierCurve ) Patch = new Geom2d_BezierCurve( PntArray );
2093 Geom2dConvert_CompCurveToBSplineCurve Concat( BCurve, Convert_QuasiAngular );
2094 Concat.Add( Patch, Tol, Standard_True );
2095 BCurve = Concat.BSplineCurve();
2099 Einf.ChangeFirstPC() = NewC2d;
2100 Handle( Geom2dAdaptor_HCurve ) hcur = new Geom2dAdaptor_HCurve( NewC2d );
2101 Handle( GeomAdaptor_HSurface ) hsur = new GeomAdaptor_HSurface( S1 );
2102 Adaptor3d_CurveOnSurface cons( hcur, hsur );
2103 Handle( Adaptor3d_HCurveOnSurface ) hcons = new Adaptor3d_HCurveOnSurface( cons );
2104 Handle( GeomAdaptor_HSurface ) hsur2 = new GeomAdaptor_HSurface( S2 );
2105 ProjLib_CompProjectedCurve ProjCurve( hsur2, hcons, Tol, Tol );
2106 Handle(ProjLib_HCompProjectedCurve) HProjector = new ProjLib_HCompProjectedCurve();
2107 HProjector->Set( ProjCurve );
2108 Standard_Real Udeb, Ufin;
2109 ProjCurve.Bounds(1, Udeb, Ufin);
2110 Standard_Integer MaxSeg = 20 + HProjector->NbIntervals(GeomAbs_C3);
2111 Approx_CurveOnSurface appr( HProjector, hsur2, Udeb, Ufin, Tol,
2112 GeomAbs_C1, 10, MaxSeg,
2113 Standard_False, Standard_False );
2114 Einf.ChangeSecondPC() = appr.Curve2d();
2115 Einf.ChangeGeometry() = appr.Curve3d();
2116 Einf.SetNewGeometry( Standard_True );
2119 return Einf.Geometry()->FirstParameter();
2121 return Einf.Geometry()->LastParameter();
2125 //=======================================================================
2126 //function : Orientation
2128 //=======================================================================
2130 static TopAbs_Orientation Orientation(const TopoDS_Shape& S,
2131 const TopoDS_Face& F)
2134 // change porting NT
2136 TopExp_Explorer expl ;
2139 while (expl.More()) {
2140 if (TopoDS::Face(expl.Current()).IsSame(F)) {
2141 return expl.Current().Orientation();
2145 return TopAbs_FORWARD;
2149 //=======================================================================
2150 //function : FindRotation
2152 //=======================================================================
2154 static Standard_Boolean FindRotation(const gp_Pln& Pl,
2155 const TopAbs_Orientation Oris,
2156 const gp_Dir& Direction,
2157 const Standard_Real Angle,
2158 const gp_Pln& NeutralPlane,
2160 Standard_Real& theta)
2162 IntAna_QuadQuadGeo i2pl(Pl,NeutralPlane,
2163 Precision::Angular(),Precision::Confusion());
2165 if (i2pl.IsDone() && i2pl.TypeInter() == IntAna_Line) {
2166 gp_Lin li = i2pl.Line(1);
2167 // Try to turn around this line
2168 gp_Dir nx = li.Direction();
2169 gp_Dir ny = Pl.Axis().Direction().Crossed(nx);
2170 Standard_Real a = Direction.Dot(nx);
2171 if (Abs(a) <=1-Precision::Angular()) {
2172 Standard_Real b = Direction.Dot(ny);
2173 Standard_Real c = Direction.Dot(Pl.Axis().Direction());
2174 Standard_Boolean direct(Pl.Position().Direct());
2175 if ((direct && Oris == TopAbs_REVERSED) ||
2176 (!direct && Oris == TopAbs_FORWARD)) {
2180 Standard_Real denom = Sqrt(1-a*a);
2181 Standard_Real Sina = Sin(Angle);
2182 if (denom>Abs(Sina)) {
2183 Standard_Real phi = ATan2(b/denom,c/denom);
2184 Standard_Real theta0 = ACos(Sina/denom);
2185 theta = theta0 - phi;
2186 if (Cos(theta) <0.) {
2187 theta = -theta0 -phi;
2189 // modified by NIZHNY-EAP Tue Nov 16 15:51:38 1999 ___BEGIN___
2190 while (Abs(theta)>M_PI) {
2191 theta = theta + M_PI*(theta<0 ? 1 : -1);
2193 // modified by NIZHNY-EAP Tue Nov 16 15:53:32 1999 ___END___
2194 Axe = li.Position();
2195 return Standard_True;
2199 return Standard_False;