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
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <Adaptor3d_CurveOnSurface.hxx>
18 #include <Adaptor3d_CurveOnSurface.hxx>
19 #include <GeomAdaptor_SurfaceOfLinearExtrusion.hxx>
20 #include <Approx_CurveOnSurface.hxx>
21 #include <BRep_Builder.hxx>
22 #include <BRep_Tool.hxx>
23 #include <BRepExtrema_ExtCF.hxx>
24 #include <BRepExtrema_ExtPC.hxx>
25 #include <BRepLib_MakeFace.hxx>
26 #include <BRepTools.hxx>
27 #include <Draft_EdgeInfo.hxx>
28 #include <Draft_FaceInfo.hxx>
29 #include <Draft_Modification.hxx>
30 #include <Draft_VertexInfo.hxx>
31 #include <ElCLib.hxx>
32 #include <ElSLib.hxx>
33 #include <Extrema_ExtPC.hxx>
34 #include <Geom2d_BezierCurve.hxx>
35 #include <Geom2d_BSplineCurve.hxx>
36 #include <Geom2d_Curve.hxx>
37 #include <Geom2d_Line.hxx>
38 #include <Geom2d_TrimmedCurve.hxx>
39 #include <Geom2dAdaptor_Curve.hxx>
40 #include <Geom2dAPI_ProjectPointOnCurve.hxx>
41 #include <Geom2dConvert.hxx>
42 #include <Geom2dConvert_CompCurveToBSplineCurve.hxx>
43 #include <Geom_BSplineCurve.hxx>
44 #include <Geom_Circle.hxx>
45 #include <Geom_Conic.hxx>
46 #include <Geom_ConicalSurface.hxx>
47 #include <Geom_Curve.hxx>
48 #include <Geom_CylindricalSurface.hxx>
49 #include <Geom_ElementarySurface.hxx>
50 #include <Geom_Ellipse.hxx>
51 #include <Geom_Hyperbola.hxx>
52 #include <Geom_Line.hxx>
53 #include <Geom_Parabola.hxx>
54 #include <Geom_Plane.hxx>
55 #include <Geom_RectangularTrimmedSurface.hxx>
56 #include <Geom_Surface.hxx>
57 #include <Geom_SurfaceOfLinearExtrusion.hxx>
58 #include <Geom_TrimmedCurve.hxx>
59 #include <GeomAdaptor_Curve.hxx>
60 #include <GeomAdaptor_Curve.hxx>
61 #include <GeomAdaptor_Surface.hxx>
62 #include <GeomAdaptor_Surface.hxx>
63 #include <GeomAPI_ProjectPointOnCurve.hxx>
64 #include <GeomAPI_ProjectPointOnSurf.hxx>
65 #include <GeomConvert_CompCurveToBSplineCurve.hxx>
66 #include <GeomInt_IntSS.hxx>
67 #include <GeomProjLib.hxx>
68 #include <gp.hxx>
69 #include <gp_Circ.hxx>
70 #include <gp_Dir.hxx>
71 #include <gp_Elips.hxx>
72 #include <gp_Hypr.hxx>
73 #include <gp_Lin.hxx>
74 #include <gp_Parab.hxx>
75 #include <gp_Pln.hxx>
76 #include <gp_Pnt.hxx>
77 #include <gp_Vec.hxx>
78 #include <IntAna_IntConicQuad.hxx>
79 #include <IntAna_QuadQuadGeo.hxx>
80 #include <IntCurveSurface_HInter.hxx>
81 #include <IntCurveSurface_IntersectionPoint.hxx>
82 #include <Precision.hxx>
83 #include <ProjLib_CompProjectedCurve.hxx>
84 #include <ProjLib_HCompProjectedCurve.hxx>
85 #include <Standard_ConstructionError.hxx>
86 #include <Standard_DomainError.hxx>
87 #include <Standard_Failure.hxx>
88 #include <Standard_NoSuchObject.hxx>
89 #include <Standard_NotImplemented.hxx>
90 #include <StdFail_NotDone.hxx>
91 #include <TColgp_Array1OfPnt2d.hxx>
92 #include <TopExp.hxx>
93 #include <TopExp_Explorer.hxx>
94 #include <TopLoc_Location.hxx>
95 #include <TopoDS.hxx>
96 #include <TopoDS_Edge.hxx>
97 #include <TopoDS_Face.hxx>
98 #include <TopoDS_Shape.hxx>
99 #include <TopoDS_Vertex.hxx>
100 #include <TopTools_ListIteratorOfListOfShape.hxx>
101 #include <TopTools_MapIteratorOfMapOfShape.hxx>
102 #include <TopTools_MapOfShape.hxx>
103
104 static Standard_Boolean Choose(const Draft_IndexedDataMapOfFaceFaceInfo&,
105 Draft_IndexedDataMapOfEdgeEdgeInfo&,
106 const TopoDS_Vertex&,
107 Draft_VertexInfo&,
108 GeomAdaptor_Curve&,
109 GeomAdaptor_Surface&);
110
111 static Standard_Real Parameter(const Handle(Geom_Curve)&,
112 const gp_Pnt&,
113 Standard_Integer&);
114
115 static Standard_Real SmartParameter(Draft_EdgeInfo&,
116 const Standard_Real EdgeTol,
117 const gp_Pnt&,
118 const Standard_Integer,
119 const Handle(Geom_Surface)&,
120 const Handle(Geom_Surface)&);
121
122 static TopAbs_Orientation Orientation(const TopoDS_Shape&,
123 const TopoDS_Face&);
124
125 static Standard_Boolean FindRotation(const gp_Pln&,
126 const TopAbs_Orientation,
127 const gp_Dir&,
128 const Standard_Real,
129 const gp_Pln&,
130 gp_Ax1&,
131 Standard_Real&);
132
133
134 //=======================================================================
135 //function : InternalAdd
136 //purpose :
137 //=======================================================================
138
InternalAdd(const TopoDS_Face & F,const gp_Dir & Direction,const Standard_Real Angle,const gp_Pln & NeutralPlane,const Standard_Boolean Flag)139 Standard_Boolean Draft_Modification::InternalAdd(const TopoDS_Face& F,
140 const gp_Dir& Direction,
141 const Standard_Real Angle,
142 const gp_Pln& NeutralPlane,
143 const Standard_Boolean Flag)
144 {
145
146 if (myFMap.Contains(F)) {
147 return (badShape.IsNull());
148 }
149
150 TopAbs_Orientation oris = Orientation(myShape,F);
151 TopLoc_Location Lo;
152 //gp_Dir NewDirection = Direction;
153 //Standard_Real NewAngle = Angle;
154 Handle(Geom_Surface) S = BRep_Tool::Surface(F,Lo);
155 S = Handle(Geom_Surface)::DownCast(S->Transformed(Lo.Transformation()));
156 if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
157 S = Handle(Geom_RectangularTrimmedSurface)::DownCast(S)->BasisSurface();
158 }
159 Handle(Geom_Surface) NewS;
160 Handle(Geom_Circle) theCircle;
161
162 Standard_Boolean postponed = (Flag == Standard_False);
163 if (postponed) {
164 Handle(Standard_Type) typS = S->DynamicType();
165 if (typS == STANDARD_TYPE(Geom_CylindricalSurface) ||
166 typS == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
167 gp_Circ Cir;
168 if (typS == STANDARD_TYPE(Geom_CylindricalSurface)) {
169 gp_Cylinder cyl =
170 Handle(Geom_CylindricalSurface)::DownCast(S)->Cylinder();
171 gp_Ax1 axcyl = cyl.Axis();
172 Cir = ElSLib::CylinderVIso( cyl.Position(), cyl.Radius(), 0.);
173 gp_Vec VV(cyl.Location(),NeutralPlane.Location());
174 Cir.Translate(VV.Dot(axcyl.Direction())*axcyl.Direction());
175 }
176 else {
177 Handle(Geom_Curve) Cbas =
178 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(S)->BasisCurve();
179 gp_Dir theDirextr =
180 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(S)->Direction();
181
182 if (Cbas->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
183 Cbas = Handle(Geom_TrimmedCurve)::DownCast(Cbas)->BasisCurve();
184 }
185 if (Cbas->IsKind(STANDARD_TYPE(Geom_Circle))) {
186 Cir = Handle(Geom_Circle)::DownCast(Cbas)->Circ();
187 gp_Dir dircir = Cir.Axis().Direction();
188 if (!Direction.IsParallel(dircir,Precision::Angular())) {
189 badShape = F;
190 errStat = Draft_FaceRecomputation;
191 return Standard_False;
192 }
193 }
194 else {
195 badShape = F;
196 errStat = Draft_FaceRecomputation;
197 return Standard_False;
198 }
199
200 gp_Ax3 Axis = NeutralPlane.Position();
201 Standard_Real L =
202 gp_Vec(Cir.Location(),Axis.Location()).
203 Dot(Axis.Direction());
204 Standard_Real Cos = theDirextr.Dot(Axis.Direction());
205 gp_Vec VV = ( L / Cos) * theDirextr;
206 Cir.Translate(VV);
207 }
208
209 theCircle = new Geom_Circle(Cir);
210
211 }
212 else {
213 postponed = Standard_False;
214 }
215 }
216
217
218 if (!postponed) {
219 NewS = NewSurface(S,oris,Direction,Angle,NeutralPlane);
220 if (NewS.IsNull()) {
221 badShape = F;
222 errStat = Draft_FaceRecomputation;
223 return Standard_False;
224 }
225 // To avoid some problems with infinite restrictions
226 const Handle(Standard_Type)& typs = NewS->DynamicType();
227 if (typs == STANDARD_TYPE(Geom_CylindricalSurface) ||
228 typs == STANDARD_TYPE(Geom_ConicalSurface)) {
229 Standard_Real umin,umax,vmin,vmax;
230 BRepTools::UVBounds(F,umin,umax,vmin,vmax);
231 if (!Precision::IsNegativeInfinite(vmin) &&
232 !Precision::IsPositiveInfinite(vmax)) {
233 Standard_Real deltav = 10.*(vmax-vmin);
234 if(typs == STANDARD_TYPE(Geom_CylindricalSurface)) {
235 vmin = vmin - deltav;
236 vmax = vmax + deltav;
237 }
238 else {
239 gp_Cone Co = Handle(Geom_ConicalSurface)::DownCast(NewS)->Cone();
240 Standard_Real Vapex = - Co.RefRadius()/Sin(Co.SemiAngle());
241 if (vmin < Vapex) { // vmax should not exceed Vapex
242 if (vmax + deltav > Vapex) {
243 vmax = Vapex;
244 vmin = vmin - 10.*(vmax - vmin);
245 // JAG debug to avoid apex
246 vmax = vmax-Precision::Confusion();
247 }
248 else {
249 vmin = vmin - deltav;
250 vmax = vmax + deltav;
251 }
252 }
253 else { // Vapex <= vmin < vmax
254 if (vmin - deltav < Vapex) {
255 vmin = Vapex;
256 vmax = vmax + 10.*(vmax - vmin);
257 // JAG debug to avoid apex
258 vmin = vmin+Precision::Confusion();
259 }
260 else {
261 vmin = vmin - deltav;
262 vmax = vmax + deltav;
263 }
264 }
265 }
266 NewS = new Geom_RectangularTrimmedSurface(NewS,0.,2.*M_PI,vmin,vmax);
267 }
268 }
269 }
270
271 if (postponed || S != NewS) {
272 Draft_FaceInfo FI(NewS,Standard_True);
273 FI.RootFace(curFace);
274 myFMap.Add(F,FI);
275 if (postponed) {
276 myFMap.ChangeFromKey(F).ChangeCurve() = theCircle;
277 }
278 }
279
280 TopExp_Explorer aExp(F,TopAbs_EDGE);
281 TopTools_MapOfShape MapOfE;
282 while (aExp.More() && badShape.IsNull()) {
283 const TopoDS_Edge& edg = TopoDS::Edge(aExp.Current());
284 if (!myEMap.Contains(edg)) {
285 Standard_Boolean addedg = Standard_False;
286 Standard_Boolean addface = Standard_False;
287 TopoDS_Face OtherF;
288 //if (BRep_Tool::IsClosed(edg,F)) {
289 if (BRepTools::IsReallyClosed(edg,F)) {
290 addedg = Standard_True;
291 addface = Standard_False;
292 }
293 else {
294 // Find the other face containing the edge.
295 TopTools_ListIteratorOfListOfShape it;
296 it.Initialize(myEFMap.FindFromKey(edg));
297 Standard_Integer nbother = 0;
298 while (it.More()) {
299 if (!it.Value().IsSame(F)) {
300 if (OtherF.IsNull()) {
301 OtherF = TopoDS::Face(it.Value());
302 }
303 nbother++;
304 }
305 it.Next();
306 }
307 if (nbother >=2) {
308 badShape = edg;
309 errStat = Draft_EdgeRecomputation;
310 }
311 else if (! OtherF.IsNull() &&
312 BRep_Tool::Continuity(edg,F,OtherF) >= GeomAbs_G1) {
313 addface= Standard_True;
314 addedg = Standard_True;
315 }
316 else if (nbother == 0) {
317 // badShape = F;
318 }
319 }
320 if (addedg) {
321 if (postponed) {
322 myFMap.ChangeFromKey(F).Add(OtherF);
323 }
324 Standard_Real f,l;
325 TopLoc_Location L;
326 Handle(Geom_Curve) C = BRep_Tool::Curve(edg,L,f,l);
327 C = Handle(Geom_Curve)::DownCast(C->Transformed(L));
328 if (C->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) {
329 C = Handle(Geom_TrimmedCurve)::DownCast(C)->BasisCurve();
330 }
331 Handle(Geom_Curve) NewC;
332 Draft_EdgeInfo EInf(Standard_True);
333 if(postponed) {
334 EInf.Add(F);
335 EInf.Add(OtherF);
336
337 // find fixed point
338 Handle(Geom_Line) aLocalGeom = Handle(Geom_Line)::DownCast(C);
339 if (aLocalGeom.IsNull()) {
340 badShape = edg;
341 errStat = Draft_EdgeRecomputation;
342 }
343 else {
344 gp_Lin lin = aLocalGeom->Lin();
345 IntAna_IntConicQuad ilipl(lin,NeutralPlane,Precision::Angular());
346 if (ilipl.IsDone() && ilipl.NbPoints() != 0){
347 EInf.Tangent(ilipl.Point(1));
348 }
349 else {
350 badShape = edg;
351 errStat = Draft_EdgeRecomputation;
352 }
353 }
354 }
355 else {
356 NewC = NewCurve(C,S,oris,Direction,Angle,NeutralPlane, Flag);
357 if (NewC.IsNull()) {
358 badShape = edg;
359 errStat = Draft_EdgeRecomputation;
360 }
361 }
362
363 Handle(Geom_TrimmedCurve) T = Handle(Geom_TrimmedCurve)::DownCast(NewC);
364 if (!T.IsNull()) NewC = T->BasisCurve();
365 EInf.ChangeGeometry() = NewC;
366
367 EInf.RootFace(curFace);
368 myEMap.Add(edg,EInf);
369 MapOfE.Add(edg);
370 if (addface) {
371 Standard_Boolean Fl = Flag;
372 Handle(Geom_Surface) alocalSurface = BRep_Tool::Surface(OtherF,Lo);
373 if (alocalSurface->DynamicType() ==
374 STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
375 alocalSurface = Handle(Geom_RectangularTrimmedSurface)::
376 DownCast(alocalSurface)->BasisSurface();
377 }
378 Handle(Standard_Type) typS = alocalSurface->DynamicType();
379 if (typS == STANDARD_TYPE(Geom_CylindricalSurface) ||
380 typS == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
381 if ( myFMap.Contains(F)) {
382 if ( Flag == Standard_False && !postponed) {
383 myFMap.RemoveKey(F);
384 TopTools_MapIteratorOfMapOfShape itm(MapOfE);
385 for ( ; itm.More(); itm.Next())
386 {
387 myEMap.RemoveKey(TopoDS::Edge(itm.Key()));
388 }
389 }
390 }
391 }
392 InternalAdd(OtherF,Direction,Angle,NeutralPlane, Fl);
393 }
394 }
395 }
396 aExp.Next();
397 }
398 return (badShape.IsNull());
399 }
400
401
402 //=======================================================================
403 //function : Propagate
404 //purpose :
405 //=======================================================================
406
Propagate()407 Standard_Boolean Draft_Modification::Propagate ()
408 {
409
410 if (!badShape.IsNull()) return Standard_False;
411
412 // Set all edges and vertices of modified faces
413 TopoDS_Face F;
414 TopoDS_Edge E;
415 TopoDS_Vertex V;
416 TopExp_Explorer editer;
417 TopExp_Explorer vtiter;
418
419 for (Standard_Integer i = 1; i <= myFMap.Extent(); i++)
420 {
421 const TopoDS_Face& Fc = myFMap.FindKey(i);
422
423 // Exploration of the edges of the face
424 editer.Init(Fc,TopAbs_EDGE);
425 while (editer.More()) {
426 E = TopoDS::Edge(editer.Current());
427
428 if (!myEMap.Contains(E)) {
429 Draft_EdgeInfo EInf(Standard_True);
430 myEMap.Add(E,EInf);
431 }
432 myEMap.ChangeFromKey(E).Add(Fc);
433
434 // Exploration of the vertices of the edge
435 vtiter.Init(E,TopAbs_VERTEX);
436 while (vtiter.More()) {
437 V = TopoDS::Vertex(vtiter.Current());
438 if (!myVMap.Contains(V)) {
439 Draft_VertexInfo VInf;
440 myVMap.Add(V,VInf);
441 }
442
443 myVMap.ChangeFromKey(V).Add(E);
444 myVMap.ChangeFromKey(V).ChangeParameter(E) = BRep_Tool::Parameter(V, E);
445 vtiter.Next();
446 }
447 editer.Next();
448 }
449 }
450
451
452 TopExp_Explorer anc;
453 Standard_Boolean found;
454
455 // Set edges containing modified vertices.
456
457 for (Standard_Integer i = 1; i <= myVMap.Extent(); i++)
458 {
459 const TopoDS_Vertex& Vt = myVMap.FindKey(i);
460
461 // Exploration of the ancestors of the vertex
462 anc.Init(myShape,TopAbs_EDGE);
463
464 while (anc.More()) {
465 E = TopoDS::Edge(anc.Current());
466 vtiter.Init(E,TopAbs_VERTEX);
467 found = Standard_False;
468 while (vtiter.More()) {
469 if (Vt.IsSame(TopoDS::Vertex(vtiter.Current()))) {
470 found = Standard_True;
471 break;
472 }
473 vtiter.Next();
474 }
475 if (found) {
476 if (!myEMap.Contains(E)) {
477 Draft_EdgeInfo EInf(Standard_False);
478 myEMap.Add(E,EInf);
479 }
480 myVMap.ChangeFromKey(Vt).Add(E);
481 myVMap.ChangeFromKey(Vt).ChangeParameter(E) = BRep_Tool::Parameter(Vt, E);
482 }
483 anc.Next();
484 }
485 }
486
487
488 // Set faces containing modified edges
489 for (Standard_Integer i = 1; i <= myEMap.Extent(); i++)
490 {
491 const TopoDS_Edge& Ed = myEMap.FindKey(i);
492 TopTools_ListIteratorOfListOfShape it;
493 for (it.Initialize(myEFMap.FindFromKey(Ed)); it.More(); it.Next()) {
494 F = TopoDS::Face(it.Value());
495 if (!myFMap.Contains(F)) {
496 TopLoc_Location L;
497 Handle(Geom_Surface) S = BRep_Tool::Surface(F,L);
498 Handle(Geom_Surface) NewS =
499 Handle(Geom_Surface)::DownCast(S->Transformed(L.Transformation()));
500
501 const Handle(Standard_Type)& typs = S->DynamicType();
502 if (typs == STANDARD_TYPE(Geom_CylindricalSurface) ||
503 typs == STANDARD_TYPE(Geom_ConicalSurface)) {
504 Standard_Real umin,umax,vmin,vmax;
505 BRepTools::UVBounds(F,umin,umax,vmin,vmax);
506 if (!Precision::IsNegativeInfinite(vmin) &&
507 !Precision::IsPositiveInfinite(vmax)) {
508 Standard_Real deltav = 10.*(vmax-vmin);
509 vmin = vmin - deltav;
510 vmax = vmax + deltav;
511 NewS = new Geom_RectangularTrimmedSurface(NewS,0.,2.*M_PI,vmin,vmax);
512 }
513 }
514
515 Draft_FaceInfo FInf(NewS,Standard_False);
516 myFMap.Add(F,FInf);
517 }
518 myEMap.ChangeFromKey(Ed).Add(F);
519 }
520 }
521
522 // Try to add faces for free borders...
523 // JAG 09.11.95
524 for (Standard_Integer i = 1; i <= myEMap.Extent(); i++)
525 {
526 Draft_EdgeInfo& Einf = myEMap.ChangeFromIndex(i);
527 if (Einf.NewGeometry() &&
528 Einf.Geometry().IsNull() &&
529 Einf.SecondFace().IsNull()) {
530
531 TopLoc_Location Loc;
532 Handle(Geom_Surface) S1 = BRep_Tool::Surface(Einf.FirstFace(),Loc);
533 S1 = Handle(Geom_Surface)::
534 DownCast(S1->Transformed(Loc.Transformation()));
535 Handle(Geom_Surface) S2;
536
537 Standard_Real f,l;
538 const TopoDS_Edge& EK = myEMap.FindKey(i);
539 Handle(Geom_Curve) C = BRep_Tool::Curve(EK,Loc,f,l);
540 C = Handle(Geom_Curve)::DownCast(C->Transformed(Loc.Transformation()));
541 if (C->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) {
542 C = Handle(Geom_TrimmedCurve)::DownCast(C)->BasisCurve();
543 }
544 if (!S1->IsKind(STANDARD_TYPE(Geom_Plane))) {
545 if (C->IsKind(STANDARD_TYPE(Geom_Conic))) {
546 gp_Ax3 thePl(Handle(Geom_Conic)::DownCast(C)->Position());
547 S2 = new Geom_Plane(thePl);
548 }
549 else if (C->DynamicType() == STANDARD_TYPE(Geom_Line)) {
550 gp_Ax1 axis;
551 if (S1->DynamicType()== STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
552 axis = Handle(Geom_ElementarySurface)::DownCast
553 (Handle(Geom_RectangularTrimmedSurface)::DownCast(S1)->
554 BasisSurface())->Axis();
555 }
556 else {
557 axis = Handle(Geom_ElementarySurface)::DownCast(S1)->Axis();
558 }
559 gp_Vec they(axis.Location(), C->Value(0.));
560 gp_Dir axz(axis.Direction().Crossed(they));
561 S2=new Geom_Plane(gp_Ax3(axis.Location(),axz,axis.Direction()));
562
563 }
564 else {
565 badShape = EK;
566 errStat = Draft_EdgeRecomputation;
567 break; // leave from for
568 }
569 }
570 else { // on the plane
571 for (Standard_Integer j = 1; j <= myVMap.Extent(); j++)
572 {
573 Draft_VertexInfo& Vinf = myVMap.ChangeFromIndex(j);
574 for (Vinf.InitEdgeIterator();Vinf.MoreEdge();Vinf.NextEdge()) {
575 if (Vinf.Edge().IsSame(EK)) {
576 break;
577 }
578 }
579 if (Vinf.MoreEdge()) {
580 for (Vinf.InitEdgeIterator();Vinf.MoreEdge();Vinf.NextEdge()) {
581 const TopoDS_Edge& edg = Vinf.Edge();
582 if (!edg.IsSame(EK)) {
583 const Draft_EdgeInfo& EI = myEMap.FindFromKey(edg);
584 if (!EI.FirstFace().IsSame(Einf.FirstFace()) &&
585 (EI.SecondFace().IsNull() ||
586 !EI.SecondFace().IsSame(Einf.FirstFace()))) {
587 break;
588 }
589 }
590 }
591 if (Vinf.MoreEdge()) {
592 Handle(Geom_Curve) C2 = BRep_Tool::Curve(Vinf.Edge(), Loc,f,l);
593 Handle(GeomAdaptor_Curve) HCur;
594 gp_Vec Direc;
595 C2 = Handle(Geom_Curve)::DownCast
596 (C2->Transformed(Loc.Transformation()));
597 if (C2->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) {
598 C2 = Handle(Geom_TrimmedCurve)::DownCast(C2)->BasisCurve();
599 }
600 if (C->DynamicType() == STANDARD_TYPE(Geom_Line)) {
601 Direc = Handle(Geom_Line)::DownCast(C)->Lin().Direction();
602 HCur = new GeomAdaptor_Curve(C2);
603
604 }
605 else if (C2->DynamicType() == STANDARD_TYPE(Geom_Line)) {
606 Direc = Handle(Geom_Line)::DownCast(C2)->Lin().Direction();
607 HCur = new GeomAdaptor_Curve(C);
608 }
609 else {
610 badShape = EK;
611 errStat = Draft_EdgeRecomputation;
612 break; // leave from while
613 }
614 GeomAdaptor_SurfaceOfLinearExtrusion SLE(HCur,Direc);
615 switch(SLE.GetType()){
616
617 case GeomAbs_Plane :
618 {
619 S2 = new Geom_Plane(SLE.Plane());
620 }
621 break;
622 case GeomAbs_Cylinder :
623 {
624 S2 = new Geom_CylindricalSurface(SLE.Cylinder());
625 }
626 break;
627 default :
628 {
629 S2 = new Geom_SurfaceOfLinearExtrusion (HCur->Curve(), Direc);
630 }
631 break;
632 }
633
634 }
635 else {
636 badShape = EK;
637 errStat = Draft_EdgeRecomputation;
638 break; // leave from while
639 }
640 break;
641 }
642 //j++;
643 }
644 }
645
646 if (badShape.IsNull()) {
647 BRep_Builder B;
648 TopoDS_Face TheNewFace;
649 B.MakeFace(TheNewFace,S2,Precision::Confusion());
650 Einf.Add(TheNewFace);
651 Draft_FaceInfo FI(S2,Standard_False);
652 myFMap.Add(TheNewFace,FI);
653 }
654 else {
655 break; // leave from for
656 }
657 // Fin JAG 09.11.95
658 }
659 }
660 return (badShape.IsNull());
661 }
662
663
664
665
666 //=======================================================================
667 //function : Perform
668 //purpose :
669 //=======================================================================
670
Perform()671 void Draft_Modification::Perform ()
672 {
673 if (!badShape.IsNull()) throw Standard_ConstructionError();
674
675 if (!myComp) {
676 myComp = Standard_True;
677 if (!Propagate()) {
678 return;
679 }
680
681 // Calculate eventual faces
682
683 for (Standard_Integer i = 1; i <= myFMap.Extent(); i++)
684 {
685 const TopoDS_Face& FK = myFMap.FindKey(i);
686 Draft_FaceInfo& Finf = myFMap.ChangeFromIndex(i);
687 if (Finf.NewGeometry() && Finf.Geometry().IsNull()) {
688 const TopoDS_Face& F1 = Finf.FirstFace();
689 const TopoDS_Face& F2 = Finf.SecondFace();
690
691 if (F1.IsNull() || F2.IsNull()) {
692 errStat = Draft_FaceRecomputation;
693 badShape = FK;
694 return;
695 }
696 Handle(Geom_Surface) S1 = myFMap.FindFromKey(F1).Geometry();
697 Handle(Geom_Surface) S2 = myFMap.FindFromKey(F2).Geometry();
698 if (S1.IsNull() || S2.IsNull()) {
699 errStat = Draft_FaceRecomputation;
700 badShape = FK;
701 return;
702 }
703 if (S1->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
704 S1 = Handle(Geom_RectangularTrimmedSurface)::
705 DownCast(S1)->BasisSurface();
706 }
707 if (S2->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
708 S2 = Handle(Geom_RectangularTrimmedSurface)::
709 DownCast(S2)->BasisSurface();
710 }
711 Handle(Geom_Plane) P1 = Handle(Geom_Plane)::DownCast(S1);
712 Handle(Geom_Plane) P2 = Handle(Geom_Plane)::DownCast(S2);
713 if (P1.IsNull() || P2.IsNull()) {
714 errStat = Draft_FaceRecomputation;
715 badShape = FK;
716 return;
717 }
718 gp_Pln pp1 = P1->Pln();
719 gp_Pln pp2 = P2->Pln();
720 IntAna_QuadQuadGeo i2p(pp1,pp2,
721 Precision::Angular(),Precision::Confusion());
722 if (!i2p.IsDone() || i2p.TypeInter() != IntAna_Line) {
723 errStat = Draft_FaceRecomputation;
724 badShape = FK;
725 return;
726 }
727
728 gp_Dir extrdir = i2p.Line(1).Direction();
729
730 // Preserve the same direction as the base face
731 Handle(Geom_Surface) RefSurf =
732 BRep_Tool::Surface(FK);
733 if (RefSurf->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
734 RefSurf =
735 Handle(Geom_RectangularTrimmedSurface)::DownCast(RefSurf)
736 ->BasisSurface();
737 }
738 gp_Dir DirRef;
739
740 if ( RefSurf->DynamicType() == STANDARD_TYPE(Geom_CylindricalSurface)) {
741 gp_Ax3 AxeRef =
742 Handle(Geom_CylindricalSurface)::DownCast(RefSurf)
743 ->Cylinder().Position();
744 DirRef = AxeRef.Direction();
745 }
746 else if (RefSurf->DynamicType() ==
747 STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
748 DirRef =
749 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(RefSurf)->Direction();
750 }
751
752 if (extrdir.Dot(DirRef) < 0.) extrdir.Reverse();
753
754 // it is possible to accelerate speed by storing the info during
755 // InternalAdd --> modification of FaceInfo to preserve the circle
756
757 Handle(Geom_Circle) CCir =
758 Handle(Geom_Circle)::DownCast(Finf.Curve());
759 Handle(Geom_Surface) NewS =
760 new Geom_SurfaceOfLinearExtrusion(CCir, extrdir);
761
762 Standard_Real umin, umax, vmin, vmax;
763 BRepTools::UVBounds(FK,umin,umax,vmin,vmax);
764 if (!Precision::IsNegativeInfinite(vmin) &&
765 !Precision::IsPositiveInfinite(vmax)) {
766 Standard_Real deltav = 2.*(vmax-vmin);
767 vmin = vmin - deltav;
768 vmax = vmax + deltav;
769 }
770
771 // very temporary
772 else {
773 vmax = 300;
774 vmin = -300;
775 }
776
777 NewS = new Geom_RectangularTrimmedSurface(NewS,0.,1.9*M_PI,vmin,vmax);
778 Finf.ChangeGeometry() = NewS;
779 }
780 }
781
782 // Calculate new edges.
783 for (Standard_Integer ii = 1; ii <= myEMap.Extent(); ii++)
784 {
785 Draft_EdgeInfo& Einf = myEMap.ChangeFromIndex(ii);
786
787 const TopoDS_Edge& theEdge = TopoDS::Edge(myEMap.FindKey(ii));
788
789 Handle(Geom_Surface) S1,S2;
790 Handle(Geom_Curve) C, newC;
791 Standard_Real f,l;
792 TopLoc_Location L;
793 C = BRep_Tool::Curve(theEdge,L,f,l);
794 C = Handle(Geom_Curve)::DownCast(C->Transformed(L.Transformation()));
795
796 if (Einf.NewGeometry() && Einf.Geometry().IsNull()) {
797 gp_Pnt ptfixe;
798 if (!Einf.IsTangent(ptfixe)) {
799 const TopoDS_Face& FirstFace = Einf.FirstFace();
800 const TopoDS_Face& SecondFace = Einf.SecondFace();
801
802 S1 = myFMap.FindFromKey(FirstFace).Geometry();
803 S2 = myFMap.FindFromKey(SecondFace).Geometry();
804
805 Standard_Integer detrompeur = 0;
806
807 // Return FirstVertex and the tangent at this point.
808 TopoDS_Vertex FV = TopExp::FirstVertex(theEdge);
809 TopoDS_Vertex LV = TopExp::LastVertex(theEdge);
810 Standard_Real pmin = 0.;
811 Standard_Real prmfv = BRep_Tool::Parameter(FV, theEdge);
812 Standard_Real prmlv = BRep_Tool::Parameter(LV, theEdge);
813 gp_Pnt pfv, plv;
814 gp_Vec d1fv,d1lv, newd1;
815 C->D1(prmfv,pfv,d1fv);
816 C->D1(prmlv,plv,d1lv);
817
818 Standard_Real TolF1 = BRep_Tool::Tolerance (FirstFace);
819 Standard_Real TolF2 = BRep_Tool::Tolerance (SecondFace);
820
821 //Pass the tolerance of the face to project
822 GeomAPI_ProjectPointOnSurf proj1 (pfv, S1, TolF1);
823 GeomAPI_ProjectPointOnSurf proj2 (plv, S1, TolF1);
824 GeomAPI_ProjectPointOnSurf proj3 (pfv, S2, TolF2);
825 GeomAPI_ProjectPointOnSurf proj4 (plv, S2, TolF2);
826
827 if (proj1.IsDone () && proj2.IsDone ()) {
828 if(proj1.LowerDistance()<= Precision::Confusion() &&
829 proj2.LowerDistance()<= Precision::Confusion()) {
830 detrompeur = 1;
831 }
832 }
833
834 if (proj3.IsDone () && proj4.IsDone ()) {
835 if(proj3.LowerDistance() <= Precision::Confusion() &&
836 proj4.LowerDistance() <= Precision::Confusion()) {
837 detrompeur = 2;
838 }
839 }
840
841 gp_Dir TheDirExtr;
842 gp_Ax3 Axis;
843 Handle(Geom_Curve) TheNewCurve;
844 Standard_Boolean KPart = Standard_False;
845
846 if ( S1->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
847 S1 = Handle(Geom_RectangularTrimmedSurface)::
848 DownCast(S1)->BasisSurface();
849 }
850 if ( S2->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
851 S2 = Handle(Geom_RectangularTrimmedSurface)::
852 DownCast(S2)->BasisSurface();
853 }
854
855 Standard_Boolean PC1 = Standard_True; // KPart on S1
856 if (S1->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion) &&
857 S2->DynamicType() == STANDARD_TYPE(Geom_Plane) ) {
858 KPart = Standard_True;
859 Axis = Handle(Geom_Plane)::DownCast(S2)->Position();
860 TheNewCurve = Handle(Geom_SurfaceOfLinearExtrusion)::
861 DownCast(S1)->BasisCurve();
862 TheDirExtr = Handle(Geom_SurfaceOfLinearExtrusion)::
863 DownCast(S1)->Direction();
864 }
865 else if (S2->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion) &&
866 S1->DynamicType() == STANDARD_TYPE(Geom_Plane) ) {
867 KPart = Standard_True;
868 PC1 = Standard_False;
869 Axis = Handle(Geom_Plane)::DownCast(S1)->Position();
870 TheNewCurve = Handle(Geom_SurfaceOfLinearExtrusion)::
871 DownCast(S2)->BasisCurve();
872 TheDirExtr = Handle(Geom_SurfaceOfLinearExtrusion)::
873 DownCast(S2)->Direction();
874 }
875 Handle(Geom_Circle) aCirc ;
876 if ( KPart) { // very temporary on circles !!!
877 aCirc = Handle(Geom_Circle)::DownCast(TheNewCurve);
878 if (aCirc.IsNull())
879 KPart = Standard_False;
880 else
881 {
882 gp_Dir AxofCirc = aCirc->Position().Direction();
883 if (AxofCirc.IsParallel(Axis.Direction(),Precision::Angular()))
884 KPart = Standard_True;
885 else
886 KPart = Standard_False;
887 }
888 }
889
890 Standard_Integer imin;
891 GeomInt_IntSS i2s;
892 if ( KPart) {
893 // direct calculation of NewC
894 Standard_Real aLocalReal =
895 gp_Vec(aCirc->Circ().Location(),Axis.Location()).
896 Dot(Axis.Direction());
897 Standard_Real Cos = TheDirExtr.Dot(Axis.Direction());
898 gp_Vec VV = ( aLocalReal / Cos) * TheDirExtr;
899 newC = Handle(Geom_Curve)::DownCast(TheNewCurve->Translated(VV));
900 // it is possible to calculate PCurve
901 Handle(Geom2d_Line) L2d
902 = new Geom2d_Line(gp_Pnt2d(0.,aLocalReal/Cos),
903 gp::DX2d());
904
905 if ( PC1)
906 Einf.ChangeFirstPC() = L2d;
907 else
908 Einf.ChangeSecondPC() = L2d;
909 }
910 else {
911 S1 = myFMap.FindFromKey(Einf.FirstFace()).Geometry();
912 S2 = myFMap.FindFromKey(Einf.SecondFace()).Geometry();
913
914
915 // PCurves are not calculated immediately for 2 reasons:
916 // 1 - If ProjLib should make an Approx, it is stupid to approximate the
917 // entire intersection curve.
918 // 2 - Additionally, if YaRev, there is a risk to not be SameRange.
919 i2s.Perform(S1,S2,Precision::Confusion(),
920 Standard_True,Standard_False,Standard_False);
921
922 if (!i2s.IsDone() || i2s.NbLines() <= 0) {
923 errStat = Draft_EdgeRecomputation;
924 badShape = theEdge;
925 return;
926 }
927
928 Standard_Real Glob2Min = RealLast();
929 GeomAdaptor_Curve TheCurve;
930
931 Standard_Integer i,j; //,jmin;
932
933 if (i2s.Line(1)->DynamicType() != STANDARD_TYPE(Geom_BSplineCurve))
934 {
935 Standard_Real Dist2Min = RealLast();
936 imin = 0;
937 for (i=1; i<= i2s.NbLines(); i++) {
938 TheCurve.Load(i2s.Line(i));
939 Extrema_ExtPC myExtPC(pfv,TheCurve);
940
941 Standard_Real locpmin = 0.;
942 if (myExtPC.IsDone()) {
943 if(myExtPC.NbExt() >= 1) {
944 Dist2Min = myExtPC.SquareDistance(1);
945 locpmin = myExtPC.Point(1).Parameter();
946 }
947 if(myExtPC.NbExt() == 2 && Dist2Min > Precision::SquareConfusion()) {
948 //to avoid incorrectly choosing the image
949 //of the first vertex of the initial edge
950 Standard_Real d1_2 = myExtPC.SquareDistance(1);
951 Standard_Real d2_2 = myExtPC.SquareDistance(2);
952 if(d1_2 > 1.21*d2_2) {
953 Dist2Min = myExtPC.SquareDistance(2);
954 locpmin = myExtPC.Point(2).Parameter();
955 }
956 else if(d2_2 > 1.21*d1_2) {
957 Dist2Min = myExtPC.SquareDistance(1);
958 locpmin = myExtPC.Point(1).Parameter();
959 }
960 else {
961 Standard_Real pfvpar = myExtPC.Point(1).Parameter();
962 Standard_Real plvpar = myExtPC.Point(2).Parameter();
963 newC = i2s.Line(i);
964
965 gp_Pnt pfvprim, plvprim;
966
967 newC->D0(pfvpar,pfvprim);
968 newC->D0(plvpar,plvprim);
969
970 Handle(Geom_Surface) theSurf;
971 if(detrompeur == 1) {
972 if(S1->DynamicType() ==
973 STANDARD_TYPE(Geom_RectangularTrimmedSurface))
974 S1 = Handle(Geom_RectangularTrimmedSurface)::
975 DownCast(S1)->BasisSurface();
976 theSurf = S1;
977
978 }
979 else if(detrompeur == 2) {
980 if(S2->DynamicType() ==
981 STANDARD_TYPE(Geom_RectangularTrimmedSurface))
982 S2 = Handle(Geom_RectangularTrimmedSurface)::
983 DownCast(S2)->BasisSurface();
984 theSurf = S2;
985 }
986 if(detrompeur != 0 && detrompeur != 4) {
987 Standard_Real ul = 0., vl = 0., uf = 0., vf = 0.;
988 Standard_Real ufprim = 0., ulprim = 0., vfprim = 0., vlprim = 0.;
989
990 if(theSurf->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
991 gp_Pln pl = Handle(Geom_Plane)::DownCast(S2)->Pln();
992 ElSLib::Parameters(pl, plv, ul, vl);
993 ElSLib::Parameters(pl, pfv, uf, vf);
994 ElSLib::Parameters(pl, plvprim, ulprim, vlprim);
995 ElSLib::Parameters(pl, pfvprim, ufprim, vfprim);
996 }
997 else if(theSurf->DynamicType() ==
998 STANDARD_TYPE(Geom_CylindricalSurface)) {
999 gp_Cylinder cy = Handle(Geom_CylindricalSurface)
1000 ::DownCast(S2)->Cylinder();
1001 ElSLib::Parameters(cy, plv, ul, vl);
1002 ElSLib::Parameters(cy, pfv, uf, vf);
1003 ElSLib::Parameters(cy, plvprim, ulprim, vlprim);
1004 ElSLib::Parameters(cy, pfvprim, ufprim, vfprim);
1005 }
1006 else detrompeur = 4;
1007
1008 if(detrompeur == 1 || detrompeur == 2) {
1009 gp_Vec2d v1((ul-ufprim), (vl-vfprim));
1010 gp_Vec2d norm((vf-vfprim), (ufprim-uf));
1011 gp_Vec2d v2((ulprim-ufprim), (vlprim-vfprim));
1012 if( (v1.Dot(norm))*(v2.Dot(norm)) < 0) {
1013 Dist2Min = myExtPC.SquareDistance(2);
1014 locpmin = myExtPC.Point(2).Parameter();
1015 }
1016 }
1017 }
1018 }
1019 }
1020 if (myExtPC.NbExt() == 1 || myExtPC.NbExt() > 2 || detrompeur ==4) {
1021 Dist2Min = myExtPC.SquareDistance(1);
1022 locpmin = myExtPC.Point(1).Parameter();
1023 for (j=2; j<=myExtPC.NbExt(); j++) {
1024 const Standard_Real Dist2 = myExtPC.SquareDistance(j);
1025 if (Dist2 < Dist2Min) {
1026 Dist2Min = Dist2;
1027 locpmin = myExtPC.Point(j).Parameter();
1028 }
1029 }
1030 }
1031 else if(myExtPC.NbExt() < 1){
1032 Standard_Real dist1_2,dist2_2;
1033 gp_Pnt p1b,p2b;
1034 myExtPC.TrimmedSquareDistances(dist1_2,dist2_2,p1b,p2b);
1035 if (dist1_2 < dist2_2) {
1036 Dist2Min = dist1_2;
1037 locpmin = TheCurve.FirstParameter();
1038 }
1039 else {
1040 Dist2Min = dist2_2;
1041 locpmin = TheCurve.LastParameter();
1042 }
1043 }
1044
1045 if (Dist2Min < Glob2Min) {
1046 Glob2Min = Dist2Min;
1047 imin = i;
1048 pmin = locpmin;
1049 }
1050 }
1051 }
1052 if (imin == 0) {
1053 errStat = Draft_EdgeRecomputation;
1054 badShape = theEdge;
1055 return;
1056 }
1057
1058 newC = i2s.Line(imin);
1059
1060 newC->D1(pmin,pfv,newd1);
1061 Standard_Boolean YaRev = d1fv.Dot(newd1) <0.;
1062
1063 if (YaRev)
1064 newC->Reverse();
1065
1066 if (i2s.HasLineOnS1(imin)) {
1067 Einf.ChangeFirstPC() = i2s.LineOnS1(imin);
1068 if ( YaRev)
1069 Einf.ChangeFirstPC()->Reverse();
1070 }
1071
1072 if (i2s.HasLineOnS2(imin)) {
1073 Einf.ChangeSecondPC() = i2s.LineOnS2(imin);
1074 if ( YaRev)
1075 Einf.ChangeSecondPC()->Reverse();
1076 }
1077 } // if (i2s.Line(1)->DynamicType() != STANDARD_TYPE(Geom_BSplineCurve))
1078 else // i2s.Line(1) is BSplineCurve
1079 {
1080 //Find the first curve to glue
1081 TColGeom_SequenceOfCurve Candidates;
1082 if (S1->DynamicType() == STANDARD_TYPE(Geom_CylindricalSurface) ||
1083 S1->DynamicType() == STANDARD_TYPE(Geom_ConicalSurface))
1084 {
1085 for (i = 1; i <= i2s.NbLines(); i++)
1086 {
1087 Handle( Geom_Curve ) aCurve = i2s.Line(i);
1088 gp_Pnt Pnt = aCurve->Value( aCurve->FirstParameter() );
1089 GeomAPI_ProjectPointOnSurf projector( Pnt, S1, Precision::Confusion() );
1090 Standard_Real U, V;
1091 projector.LowerDistanceParameters( U, V );
1092 if (Abs(U) <= Precision::Confusion() || Abs(U-2.*M_PI) <= Precision::Confusion())
1093 Candidates.Append( aCurve );
1094 else
1095 {
1096 Pnt = aCurve->Value( aCurve->LastParameter() );
1097 projector.Init( Pnt, S1, Precision::Confusion() );
1098 projector.LowerDistanceParameters( U, V );
1099 if (Abs(U) <= Precision::Confusion() || Abs(U-2.*M_PI) <= Precision::Confusion())
1100 {
1101 aCurve->Reverse();
1102 Candidates.Append( aCurve );
1103 }
1104 }
1105 }
1106
1107 if(Candidates.Length() == 0)
1108 {
1109 //errStat = Draft_EdgeRecomputation;
1110 //badShape = TopoDS::Edge(ite.Key());
1111 //return;
1112 for (i = 1; i <= i2s.NbLines(); i++)
1113 Candidates.Append( i2s.Line(i) );
1114 }
1115 }
1116 else
1117 {
1118 for (i = 1; i <= i2s.NbLines(); i++)
1119 Candidates.Append( i2s.Line(i) );
1120 }
1121
1122 Handle( Geom_Curve ) FirstCurve;
1123 if (Candidates.Length() > 1)
1124 {
1125 Standard_Real DistMin = Precision::Infinite();
1126 for (i = 1; i <= Candidates.Length(); i++)
1127 {
1128 Handle( Geom_Curve ) aCurve = Candidates(i);
1129 gp_Pnt Pnt = aCurve->Value( aCurve->FirstParameter() );
1130 const Standard_Real Dist = Pnt.Distance( pfv );
1131 if (Dist - DistMin < -Precision::Confusion())
1132 {
1133 DistMin = Dist;
1134 FirstCurve = aCurve;
1135 }
1136 }
1137 }
1138 else
1139 FirstCurve = Candidates(1);
1140
1141 //Glueing
1142 TColGeom_SequenceOfCurve Curves;
1143 for (i = 1; i <= i2s.NbLines(); i++)
1144 if (FirstCurve != i2s.Line(i))
1145 Curves.Append( i2s.Line(i) );
1146
1147 TColGeom_SequenceOfCurve ToGlue;
1148 gp_Pnt EndPoint = FirstCurve->Value( FirstCurve->LastParameter() );
1149 Standard_Boolean added = Standard_True;
1150 while (added)
1151 {
1152 added = Standard_False;
1153 for (i = 1; i <= Curves.Length(); i++)
1154 {
1155 Handle( Geom_Curve ) aCurve = Curves(i);
1156 gp_Pnt pfirst, plast;
1157 pfirst = aCurve->Value( aCurve->FirstParameter() );
1158 plast = aCurve->Value( aCurve->LastParameter() );
1159 if (pfirst.Distance( EndPoint ) <= Precision::Confusion())
1160 {
1161 ToGlue.Append( aCurve );
1162 EndPoint = plast;
1163 Curves.Remove(i);
1164 added = Standard_True;
1165 break;
1166 }
1167 if (plast.Distance( EndPoint ) <= Precision::Confusion())
1168 {
1169 aCurve->Reverse();
1170 ToGlue.Append( aCurve );
1171 EndPoint = pfirst;
1172 Curves.Remove(i);
1173 added = Standard_True;
1174 break;
1175 }
1176 }
1177 }
1178
1179 if (FirstCurve.IsNull()) {
1180 errStat = Draft_EdgeRecomputation;
1181 badShape = theEdge;
1182 return;
1183 }
1184
1185 GeomConvert_CompCurveToBSplineCurve Concat( Handle(Geom_BSplineCurve)::DownCast(FirstCurve) );
1186 for (i = 1; i <= ToGlue.Length(); i++)
1187 Concat.Add( Handle(Geom_BSplineCurve)::DownCast(ToGlue(i)), Precision::Confusion(), Standard_True );
1188
1189 newC = Concat.BSplineCurve();
1190
1191 TheCurve.Load( newC );
1192 Extrema_ExtPC myExtPC( pfv, TheCurve );
1193 Standard_Real Dist2Min = RealLast();
1194 for (i = 1; i <= myExtPC.NbExt(); i++)
1195 {
1196 if (myExtPC.IsMin(i))
1197 {
1198 const Standard_Real Dist2 = myExtPC.SquareDistance(i);
1199 if (Dist2 < Dist2Min)
1200 {
1201 Dist2Min = Dist2;
1202 pmin = myExtPC.Point(i).Parameter();
1203 }
1204 }
1205 }
1206 newC->D1(pmin,pfv,newd1);
1207 Standard_Boolean YaRev = d1fv.Dot(newd1) < 0.;
1208
1209 if (YaRev)
1210 newC->Reverse();
1211 /*
1212 if (i2s.HasLineOnS1(imin)) {
1213 Einf.ChangeFirstPC() = i2s.LineOnS1(imin);
1214 if ( YaRev)
1215 Einf.ChangeFirstPC()->Reverse();
1216 }
1217
1218 if (i2s.HasLineOnS2(imin)) {
1219 Einf.ChangeSecondPC() = i2s.LineOnS2(imin);
1220 if ( YaRev)
1221 Einf.ChangeSecondPC()->Reverse();
1222 }
1223 */
1224 } // else: i2s.NbLines() > 2 && S1 is Cylinder or Cone
1225
1226 Einf.Tolerance(Max(Einf.Tolerance(), i2s.TolReached3d()));
1227 } // End step KPart
1228 }
1229 else { // case of tangency
1230 const TopoDS_Face& F1 = Einf.FirstFace();
1231 const TopoDS_Face& F2 = Einf.SecondFace();
1232
1233 Handle(Geom_Surface) aLocalS1 = myFMap.FindFromKey(F1).Geometry();
1234 Handle(Geom_Surface) aLocalS2 = myFMap.FindFromKey(F2).Geometry();
1235 if (aLocalS1.IsNull() || aLocalS2.IsNull()) {
1236 errStat = Draft_EdgeRecomputation;
1237 badShape = theEdge;
1238 return;
1239 }
1240 if (aLocalS1->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1241 aLocalS1 = Handle(Geom_RectangularTrimmedSurface)::
1242 DownCast(aLocalS1)->BasisSurface();
1243 }
1244 if (aLocalS2->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1245 aLocalS2 = Handle(Geom_RectangularTrimmedSurface)::
1246 DownCast(aLocalS2)->BasisSurface();
1247 }
1248
1249 gp_Dir dirextr;
1250 //Standard_Boolean dirfound = Standard_False;
1251 if (aLocalS1->DynamicType() == STANDARD_TYPE(Geom_CylindricalSurface)) {
1252 gp_Cylinder cyl =
1253 Handle(Geom_CylindricalSurface)::DownCast(aLocalS1)->Cylinder();
1254 dirextr = cyl.Axis().Direction();
1255 //dirfound = Standard_True;
1256 // see direction...
1257
1258 }
1259 else if (aLocalS1->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
1260 dirextr = Handle(Geom_SurfaceOfLinearExtrusion)::
1261 DownCast(aLocalS1)->Direction();
1262 //dirfound = Standard_True;
1263 // see direction...
1264
1265 // Here it is possible to calculate PCurve.
1266 Handle(Geom_SurfaceOfLinearExtrusion) SEL =
1267 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(aLocalS1);
1268 Handle(Geom_Circle) GCir =
1269 Handle(Geom_Circle)::DownCast(SEL->BasisCurve());
1270 if ( !GCir.IsNull()) {
1271 Standard_Real U = ElCLib::Parameter(GCir->Circ(),ptfixe);
1272 Handle(Geom2d_Line) PC1 =
1273 new Geom2d_Line(gp_Pnt2d(U,0.),gp::DY2d());
1274 Einf.ChangeFirstPC() = PC1;
1275 }
1276 }
1277
1278 else if (aLocalS2->DynamicType() == STANDARD_TYPE(Geom_CylindricalSurface)) {
1279 gp_Cylinder cyl =
1280 Handle(Geom_CylindricalSurface)::DownCast(aLocalS2)->Cylinder();
1281 dirextr = cyl.Axis().Direction();
1282 // dirfound = Standard_True;
1283 // see direction...
1284
1285 }
1286 else if (aLocalS2->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
1287 dirextr = Handle(Geom_SurfaceOfLinearExtrusion)::
1288 DownCast(aLocalS2)->Direction();
1289 // dirfound = Standard_True;
1290 // see direction...
1291
1292 // Here it is possible to calculate PCurve.
1293 Handle(Geom_SurfaceOfLinearExtrusion) SEL =
1294 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(aLocalS2);
1295 Handle(Geom_Circle) GCir =
1296 Handle(Geom_Circle)::DownCast(SEL->BasisCurve());
1297 if ( !GCir.IsNull()) {
1298 Standard_Real U = ElCLib::Parameter(GCir->Circ(),ptfixe);
1299 Handle(Geom2d_Line) PC2 =
1300 new Geom2d_Line(gp_Pnt2d(U,0.),gp::DY2d());
1301 Einf.ChangeSecondPC() = PC2;
1302 }
1303 }
1304 newC = new Geom_Line(ptfixe,dirextr);
1305
1306 gp_Pnt pfv;
1307 gp_Vec d1fv,newd1;
1308 C->D1(0.,pfv,d1fv);
1309 newC->D1(0.,pfv,newd1);
1310 Standard_Boolean YaRev = d1fv.Dot(newd1) <0.;
1311 if (YaRev) {
1312 newC->Reverse();
1313 if(!Einf.FirstPC().IsNull()) {
1314 Einf.ChangeFirstPC()->Reverse();
1315 }
1316 if(!Einf.SecondPC().IsNull()) {
1317 Einf.ChangeSecondPC()->Reverse();
1318 }
1319 }
1320 }
1321
1322 Handle(Geom_TrimmedCurve) T = Handle(Geom_TrimmedCurve)::DownCast(newC);
1323 if (!T.IsNull()) newC = T->BasisCurve();
1324 Einf.ChangeGeometry() = newC;
1325 }
1326 else if (!Einf.NewGeometry()){
1327 // set existing curve 3D
1328 Handle(Geom_TrimmedCurve) T = Handle(Geom_TrimmedCurve)::DownCast(C);
1329 if (!T.IsNull()) C = T->BasisCurve();
1330 Einf.ChangeGeometry() = C;
1331 }
1332 }
1333
1334 // Calculate new vertices.
1335
1336 Handle(GeomAdaptor_Curve) HAC = new GeomAdaptor_Curve;
1337 Handle(GeomAdaptor_Surface) HAS = new GeomAdaptor_Surface;
1338
1339 for (Standard_Integer ii = 1; ii <= myVMap.Extent(); ii++)
1340 {
1341 GeomAdaptor_Curve& AC = *HAC;
1342 GeomAdaptor_Surface& AS = *HAS;
1343
1344 const TopoDS_Vertex& TVV = myVMap.FindKey(ii);
1345 Draft_VertexInfo& Vinf = myVMap.ChangeFromIndex(ii);
1346 if (!Choose(myFMap,myEMap,TVV,Vinf,AC,AS)) {
1347
1348 // no concerted edge => alignment of two consecutive edges.
1349 gp_Pnt pvt;
1350 Vinf.ChangeGeometry() = pvt;
1351 Vinf.InitEdgeIterator();
1352 if (Vinf.MoreEdge()) {
1353 const TopoDS_Edge& Edg1 = Vinf.Edge();
1354 //const Draft_EdgeInfo& Einf1 = myEMap(Edg1);
1355 Draft_EdgeInfo& Einf1 = myEMap.ChangeFromKey(Edg1);
1356 gp_Pnt vtori = BRep_Tool::Pnt(TVV);
1357 //Einf1.Geometry()->D0(Vinf.Parameter(Edg1), pvt);
1358 GeomAPI_ProjectPointOnCurve Projector( vtori, Einf1.Geometry() ); //patch
1359 pvt = Projector.NearestPoint();
1360
1361 #ifdef OCCT_DEBUG
1362 static Standard_Integer VertexRecomp = 1;
1363 if (VertexRecomp!=0) {
1364 std::cout << "pori :" << vtori.X() << " " << vtori.Y() << " " << vtori.Z() << std::endl;
1365 std::cout << " Edg 1 :" << Vinf.Parameter(Edg1) << std::endl;
1366 std::cout << "pvt :" << pvt.X() << " " << pvt.Y() << " " << pvt.Z() << std::endl;
1367 }
1368 #endif
1369
1370 Standard_Real dion=pvt.SquareDistance(vtori);
1371 Vinf.NextEdge();
1372 if (Vinf.MoreEdge()) {
1373 const TopoDS_Edge& Edg2 = Vinf.Edge();
1374 //const Draft_EdgeInfo& Einf2 = myEMap(Edg2);
1375 Draft_EdgeInfo& Einf2 = myEMap.ChangeFromKey(Edg2);
1376 // Standard_Real f;
1377 gp_Pnt opvt;
1378 Einf2.Geometry()->D0(Vinf.Parameter(Edg2), opvt);
1379
1380 #ifdef OCCT_DEBUG
1381 if (VertexRecomp!=0) {
1382 std::cout << " Edg 2 :" << Vinf.Parameter(Vinf.Edge()) << std::endl;
1383 std::cout << "opvt " << opvt.X() << " " << opvt.Y() << " " << opvt.Z() << std::endl;
1384 }
1385 #endif
1386
1387 if (opvt.SquareDistance(vtori) < dion) {
1388 pvt = opvt;
1389 }
1390 //Vinf.ChangeParameter(Edg2) = Parameter(Einf2.Geometry(), pvt);
1391 Standard_Integer done;
1392 Standard_Real param = Parameter(Einf2.Geometry(), pvt, done);
1393 if (done != 0)
1394 {
1395 Handle(Geom_Surface) S1 = myFMap.FindFromKey(Einf2.FirstFace()).Geometry();
1396 Handle(Geom_Surface) S2 = myFMap.FindFromKey(Einf2.SecondFace()).Geometry();
1397 Vinf.ChangeParameter(Edg2) = SmartParameter( Einf2, BRep_Tool::Tolerance(Edg2), pvt, done, S1, S2 );
1398 }
1399 else
1400 Vinf.ChangeParameter(Edg2) = param;
1401 }
1402
1403 Vinf.ChangeGeometry() = pvt;
1404 //Vinf.ChangeParameter(Edg1) = Parameter(Einf1.Geometry(), pvt);
1405 Standard_Integer done;
1406 Standard_Real param = Parameter(Einf1.Geometry(), pvt, done);
1407 if (done != 0)
1408 {
1409 Handle(Geom_Surface) S1 = myFMap.FindFromKey(Einf1.FirstFace()).Geometry();
1410 Handle(Geom_Surface) S2 = myFMap.FindFromKey(Einf1.SecondFace()).Geometry();
1411 Vinf.ChangeParameter(Edg1) = SmartParameter( Einf1, BRep_Tool::Tolerance(Edg1), pvt, done, S1, S2 );
1412 }
1413 else
1414 Vinf.ChangeParameter(Edg1) = param;
1415 continue;
1416 }
1417
1418
1419 errStat = Draft_VertexRecomputation;
1420 badShape = TVV;
1421 return;
1422 }
1423
1424 IntCurveSurface_HInter myintcs;
1425 myintcs.Perform(HAC,HAS);
1426 if (!myintcs.IsDone()) {
1427 errStat = Draft_VertexRecomputation;
1428 badShape = TVV;
1429 return;
1430 }
1431
1432 gp_Pnt vtori = BRep_Tool::Pnt(TVV);
1433 gp_Pnt pvt;
1434
1435 Standard_Integer nbsol = myintcs.NbPoints();
1436 if (nbsol <= 0)
1437 {
1438 Extrema_ExtCS extr( AC, AS, Precision::PConfusion(), Precision::PConfusion() );
1439
1440 if(!extr.IsDone() || extr.NbExt() == 0) {
1441 errStat = Draft_VertexRecomputation;
1442 badShape = TVV;
1443 return;
1444 }
1445
1446
1447 Standard_Real disref = RealLast();
1448 Standard_Integer iref = 0;
1449 Extrema_POnCurv Pc;
1450 Extrema_POnSurf Ps;
1451 for (Standard_Integer i = 1; i <= extr.NbExt(); i++)
1452 {
1453 extr.Points( i, Pc, Ps );
1454 Standard_Real distemp = Pc.Value().SquareDistance(vtori);
1455 if ( distemp < disref)
1456 {
1457 disref = distemp;
1458 iref = i;
1459 }
1460 }
1461 extr.Points( iref, Pc, Ps );
1462 pvt = Pc.Value();
1463 }
1464 else
1465 {
1466 Standard_Real disref = RealLast();
1467 Standard_Integer iref = 0;
1468 for (Standard_Integer i = 1; i <= nbsol; i++)
1469 {
1470 Standard_Real distemp = myintcs.Point(i).Pnt().SquareDistance(vtori);
1471 if ( distemp < disref)
1472 {
1473 disref = distemp;
1474 iref = i;
1475 }
1476 }
1477 pvt = myintcs.Point(iref).Pnt();
1478 }
1479
1480 Vinf.ChangeGeometry() = pvt;
1481
1482 for (Vinf.InitEdgeIterator();Vinf.MoreEdge(); Vinf.NextEdge()) {
1483 const TopoDS_Edge& Edg = Vinf.Edge();
1484 Standard_Real initpar = Vinf.Parameter(Edg);
1485 //const Draft_EdgeInfo& Einf = myEMap(Edg);
1486 Draft_EdgeInfo& Einf = myEMap.ChangeFromKey(Edg);
1487 //Vinf.ChangeParameter(Edg) = Parameter(Einf.Geometry(),pvt);
1488 Standard_Integer done;
1489 Standard_Real param = Parameter(Einf.Geometry(), pvt, done);
1490 if (done != 0)
1491 {
1492 Handle(Geom_Surface) S1 = myFMap.FindFromKey(Einf.FirstFace()).Geometry();
1493 Handle(Geom_Surface) S2 = myFMap.FindFromKey(Einf.SecondFace()).Geometry();
1494 Vinf.ChangeParameter(Edg) = SmartParameter( Einf, BRep_Tool::Tolerance(Edg), pvt, done, S1, S2 );
1495 }
1496 else
1497 {
1498 if(Abs(initpar - param) > Precision::PConfusion())
1499 {
1500 Standard_Real f, l;
1501 TopLoc_Location Loc;
1502 const Handle(Geom_Curve)& aC = BRep_Tool::Curve(Edg, Loc, f, l);
1503 if(aC->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve))
1504 {
1505 Einf.SetNewGeometry(Standard_True);
1506 }
1507 }
1508 Vinf.ChangeParameter(Edg) = param;
1509 }
1510 }
1511 }
1512 }
1513
1514 // small loop of validation/protection
1515
1516 for (Standard_Integer i = 1; i <= myEMap.Extent(); i++)
1517 {
1518 const TopoDS_Edge& edg = TopoDS::Edge(myEMap.FindKey(i));
1519
1520 TopoDS_Vertex Vf,Vl;
1521 TopExp::Vertices(edg,Vf,Vl);
1522 if (edg.Orientation() == TopAbs_REVERSED) {
1523 Vf.Reverse();
1524 Vl.Reverse();
1525 }
1526
1527 if(myVMap.Contains(Vf) && myVMap.Contains(Vl))
1528 {
1529 //Here, we compare directions of the source edge (from input shape)
1530 //and corresponding selected part of the intersection edge.
1531 //If these directions are opposite then we reverse intersection edge
1532 //and recompute corresponding vertex-parameters.
1533
1534 Standard_Real aParF = myVMap.ChangeFromKey(Vf).Parameter(edg);
1535 Standard_Real aParL = myVMap.ChangeFromKey(Vl).Parameter(edg);
1536
1537 if(aParL < aParF)
1538 {
1539 Draft_EdgeInfo& aEinf = myEMap.ChangeFromKey(edg);
1540 TopLoc_Location aLoc;
1541 Standard_Real aF = 0.0, aL = 0.0;
1542 const Handle(Geom_Curve) aSCurve = BRep_Tool::Curve(edg, aF, aL);
1543 Handle(Geom_Curve) anIntCurv = aEinf.Geometry();
1544 gp_Pnt aPf, aPl;
1545 gp_Vec aDirNF, aDirNL, aDirOF, aDirOL;
1546 aSCurve->D1(BRep_Tool::Parameter(Vf, edg), aPf, aDirOF);
1547 aSCurve->D1(BRep_Tool::Parameter(Vl, edg), aPl, aDirOL);
1548 anIntCurv->D1(aParF, aPf, aDirNF);
1549 anIntCurv->D1(aParL, aPl, aDirNL);
1550
1551 Standard_Real aSqMagn = aDirNF.SquareMagnitude();
1552
1553 if (aSqMagn > Precision::SquareConfusion())
1554 aDirNF.Divide(sqrt(aSqMagn));
1555
1556 aSqMagn = aDirNL.SquareMagnitude();
1557 if (aSqMagn > Precision::SquareConfusion())
1558 aDirNL.Divide(sqrt(aSqMagn));
1559
1560 aSqMagn = aDirOF.SquareMagnitude();
1561 if (aSqMagn > Precision::SquareConfusion())
1562 aDirOF.Divide(sqrt(aSqMagn));
1563
1564 aSqMagn = aDirOL.SquareMagnitude();
1565 if (aSqMagn > Precision::SquareConfusion())
1566 aDirOL.Divide(sqrt(aSqMagn));
1567
1568 const Standard_Real aCosF = aDirNF.Dot(aDirOF), aCosL = aDirNL.Dot(aDirOL);
1569 const Standard_Real aCosMax = Abs(aCosF) > Abs(aCosL) ? aCosF : aCosL;
1570
1571 if(aCosMax < 0.0)
1572 {
1573 Standard_Integer anErr = 0;
1574 anIntCurv->Reverse();
1575 aEinf.ChangeGeometry() = anIntCurv;
1576 Standard_Real aPar = Parameter(aEinf.Geometry(), aPf, anErr);
1577 if(anErr == 0)
1578 {
1579 myVMap.ChangeFromKey(Vf).ChangeParameter(edg) = aPar;
1580 }
1581 aPar = Parameter(aEinf.Geometry(), aPl, anErr);
1582 if(anErr == 0)
1583 {
1584 myVMap.ChangeFromKey(Vl).ChangeParameter(edg) = aPar;
1585 }
1586 }
1587 }
1588 }
1589
1590 Standard_Real pf,pl,tolerance;
1591 if (!NewParameter(Vf,edg,pf,tolerance)) {
1592 pf = BRep_Tool::Parameter(Vf,edg);
1593 }
1594 if (!NewParameter(Vl,edg,pl,tolerance)) {
1595 pl = BRep_Tool::Parameter(Vl,edg);
1596 }
1597 if (pl <= pf) {
1598 // const Handle(Geom_Curve) gc=ite.Value().Geometry();
1599 // if (!gc.IsNull()) {
1600 // pl = gc->LastParameter();
1601 // pf = gc->FirstParameter();
1602 // }
1603 Handle( Geom_Curve ) theCurve = myEMap.FindFromKey(edg).Geometry();
1604 if (theCurve->IsClosed())
1605 {
1606 // pf >= pl
1607 Standard_Real FirstPar = theCurve->FirstParameter(), LastPar = theCurve->LastParameter();
1608 Standard_Real pconf = Precision::PConfusion();
1609 if (Abs( pf - LastPar ) <= pconf)
1610 pf = FirstPar;
1611 else if (Abs( pl - FirstPar ) <= pconf)
1612 pl = LastPar;
1613
1614 if(pl <= pf) {
1615 pl += (LastPar-FirstPar);
1616 }
1617
1618 }
1619 if (pl <= pf) {
1620 errStat = Draft_EdgeRecomputation;
1621 badShape = edg;
1622 return;
1623 }
1624 }
1625 if (myVMap.Contains( Vf ))
1626 myVMap.ChangeFromKey(Vf).ChangeParameter(edg) = pf;
1627 if (myVMap.Contains( Vl ))
1628 myVMap.ChangeFromKey(Vl).ChangeParameter(edg) = pl;
1629 }
1630 }
1631
1632
1633
1634 //=======================================================================
1635 //function : NewSurface
1636 //purpose :
1637 //=======================================================================
1638
Handle(Geom_Surface)1639 Handle(Geom_Surface) Draft_Modification::NewSurface
1640 (const Handle(Geom_Surface)& S,
1641 const TopAbs_Orientation Oris,
1642 const gp_Dir& Direction,
1643 const Standard_Real Angle,
1644 const gp_Pln& NeutralPlane)
1645 {
1646 Handle(Geom_Surface) NewS;
1647
1648 Handle(Standard_Type) TypeS = S->DynamicType();
1649
1650 if (TypeS == STANDARD_TYPE(Geom_Plane)) {
1651 gp_Pln Pl = Handle(Geom_Plane)::DownCast(S)->Pln();
1652 gp_Ax1 Axe;
1653 Standard_Real Theta;
1654 if (FindRotation(Pl,Oris,Direction,Angle,NeutralPlane,Axe,Theta)) {
1655 if ( Abs(Theta) > Precision::Angular()) {
1656 NewS = Handle(Geom_Surface)::DownCast(S->Rotated(Axe,Theta));
1657 }
1658 else {
1659 NewS = S;
1660 }
1661 }
1662 }
1663 else if (TypeS == STANDARD_TYPE(Geom_CylindricalSurface)) {
1664 Standard_Real testdir = Direction.Dot(NeutralPlane.Axis().Direction());
1665 if (Abs(testdir) <= 1.-Precision::Angular()) {
1666 #ifdef OCCT_DEBUG
1667 std::cout << "NewSurfaceCyl:Draft_Direction_and_Neutral_Perpendicular" << std::endl;
1668 #endif
1669 return NewS;
1670 }
1671 gp_Cylinder Cy = Handle(Geom_CylindricalSurface)::DownCast(S)->Cylinder();
1672 testdir = Direction.Dot(Cy.Axis().Direction());
1673 if (Abs(testdir) <= 1.-Precision::Angular()) {
1674 #ifdef OCCT_DEBUG
1675 std::cout << "NewSurfaceCyl:Draft_Direction_and_Cylinder_Perpendicular" << std::endl;
1676 #endif
1677 return NewS;
1678 }
1679 if (Abs(Angle) > Precision::Angular())
1680 {
1681 IntAna_QuadQuadGeo i2s;
1682 i2s.Perform(NeutralPlane,Cy,Precision::Angular(),Precision::Confusion());
1683 Standard_Boolean isIntDone = i2s.IsDone();
1684
1685 if(i2s.TypeInter() == IntAna_Ellipse)
1686 {
1687 const gp_Elips anEl = i2s.Ellipse(1);
1688 const Standard_Real aMajorR = anEl.MajorRadius();
1689 const Standard_Real aMinorR = anEl.MinorRadius();
1690 isIntDone = (aMajorR < 100000.0 * aMinorR);
1691 }
1692
1693 if (!isIntDone || i2s.TypeInter() != IntAna_Circle) {
1694 #ifdef OCCT_DEBUG
1695 std::cout << "NewSurfaceCyl:Draft_Intersection_Neutral_Cylinder_NotDone" << std::endl;
1696 #endif
1697 return NewS;
1698 }
1699 gp_Ax3 axcone = Cy.Position();
1700 // Pb : Where is the material???
1701 Standard_Real alpha = Angle;
1702 Standard_Boolean direct(axcone.Direct());
1703 if ((direct && Oris == TopAbs_REVERSED) ||
1704 (!direct && Oris == TopAbs_FORWARD)) {
1705 alpha = -alpha;
1706 }
1707
1708 gp_Pnt Center = i2s.Circle(1).Location();
1709 if (testdir <0.) {
1710 alpha = -alpha;
1711 }
1712 Standard_Real Z = ElCLib::LineParameter(Cy.Axis(),Center);
1713 Standard_Real Rad = Cy.Radius()+Z*Tan(alpha);
1714 if (Rad < 0.) {
1715 Rad = -Rad;
1716 }
1717 else {
1718 alpha = -alpha;
1719 }
1720 gp_Cone co(axcone,alpha,Rad);
1721 NewS = new Geom_ConicalSurface(co);
1722 }
1723 else {
1724 NewS = S;
1725 }
1726 }
1727 else if (TypeS == STANDARD_TYPE(Geom_ConicalSurface)) {
1728
1729 Standard_Real testdir = Direction.Dot(NeutralPlane.Axis().Direction());
1730 if (Abs(testdir) <= 1.-Precision::Angular()) {
1731 #ifdef OCCT_DEBUG
1732 std::cout << "NewSurfaceCone:Draft_Direction_and_Neutral_Perpendicular" << std::endl;
1733 #endif
1734 return NewS;
1735 }
1736
1737 gp_Cone Co1 = Handle(Geom_ConicalSurface)::DownCast(S)->Cone();
1738
1739 testdir = Direction.Dot(Co1.Axis().Direction());
1740 if (Abs(testdir) <= 1.-Precision::Angular()) {
1741 #ifdef OCCT_DEBUG
1742 std::cout << "NewSurfaceCone:Draft_Direction_and_Cone_Perpendicular" << std::endl;
1743 #endif
1744 return NewS;
1745 }
1746
1747
1748 IntAna_QuadQuadGeo i2s;
1749 i2s.Perform(NeutralPlane,Co1,Precision::Angular(),Precision::Confusion());
1750 if (!i2s.IsDone() || i2s.TypeInter() != IntAna_Circle) {
1751 #ifdef OCCT_DEBUG
1752 std::cout << "NewSurfaceCone:Draft_Intersection_Neutral_Conical_NotDone" << std::endl;
1753 #endif
1754 return NewS;
1755 }
1756 gp_Ax3 axcone = Co1.Position();
1757 // Pb : Where is the material???
1758 Standard_Real alpha = Angle;
1759 Standard_Boolean direct(axcone.Direct());
1760 if ((direct && Oris == TopAbs_REVERSED) ||
1761 (!direct && Oris == TopAbs_FORWARD)) {
1762 alpha = -alpha;
1763 }
1764
1765 gp_Pnt Center = i2s.Circle(1).Location();
1766 if (Abs(Angle) > Precision::Angular()) {
1767 if (testdir <0.) {
1768 alpha = -alpha;
1769 }
1770 Standard_Real Z = ElCLib::LineParameter(Co1.Axis(),Center);
1771 Standard_Real Rad = i2s.Circle(1).Radius()+Z*Tan(alpha);
1772 if (Rad < 0.) {
1773 Rad = -Rad;
1774 }
1775 else {
1776 alpha = -alpha;
1777 }
1778 if (Abs(alpha-Co1.SemiAngle()) < Precision::Angular()) {
1779 NewS = S;
1780 }
1781 else {
1782 gp_Cone co(axcone,alpha,Rad);
1783 NewS = new Geom_ConicalSurface(co);
1784 }
1785 }
1786 else {
1787 NewS = new
1788 Geom_CylindricalSurface(gp_Cylinder(axcone,i2s.Circle(1).Radius()));
1789 }
1790 }
1791 else {
1792 #ifdef OCCT_DEBUG
1793 std::cout << "NewSurface:Draft_SurfNotYetImplemented" << std::endl;
1794 #endif
1795 }
1796 return NewS;
1797 }
1798
1799
1800 //=======================================================================
1801 //function : NewCurve
1802 //purpose :
1803 //=======================================================================
1804
Handle(Geom_Curve)1805 Handle(Geom_Curve) Draft_Modification::NewCurve
1806 (const Handle(Geom_Curve)& C,
1807 const Handle(Geom_Surface)& S,
1808 const TopAbs_Orientation Oris,
1809 const gp_Dir& Direction,
1810 const Standard_Real Angle,
1811 const gp_Pln& NeutralPlane,
1812 const Standard_Boolean )
1813
1814 {
1815 Handle(Geom_Curve) NewC;
1816
1817 Handle(Standard_Type) TypeS = S->DynamicType();
1818
1819 if (TypeS == STANDARD_TYPE(Geom_Plane)) {
1820 gp_Pln Pl = Handle(Geom_Plane)::DownCast(S)->Pln();
1821 gp_Ax1 Axe;
1822 Standard_Real Theta;
1823 if (FindRotation(Pl,Oris,Direction,Angle,NeutralPlane,Axe,Theta)) {
1824 if ( Abs(Theta) > Precision::Angular()) {
1825 NewC = Handle(Geom_Curve)::DownCast(C->Rotated(Axe,Theta));
1826 }
1827 else {
1828 NewC = C;
1829 }
1830 }
1831 return NewC;
1832 }
1833
1834
1835 if (C->DynamicType() != STANDARD_TYPE(Geom_Line)) {
1836 return NewC;
1837 }
1838
1839
1840 gp_Lin lin = Handle(Geom_Line)::DownCast(C)->Lin();
1841 // Standard_Real testdir = Direction.Dot(lin.Direction());
1842 // if (Abs(testdir) <= 1.-Precision::Angular()) {
1843 // return NewC;
1844 // }
1845 gp_Dir Norm;
1846 if (TypeS == STANDARD_TYPE(Geom_CylindricalSurface)) {
1847 Standard_Real U,V;
1848 gp_Vec d1u,d1v;
1849 gp_Pnt pbid;
1850 gp_Cylinder Cy = Handle(Geom_CylindricalSurface)::DownCast(S)->Cylinder();
1851 ElSLib::Parameters(Cy,lin.Location(),U,V);
1852 ElSLib::D1(U,V,Cy,pbid,d1u,d1v);
1853 Norm = d1u.Crossed(d1v);
1854 }
1855 else if (TypeS == STANDARD_TYPE(Geom_ConicalSurface)) {
1856 Standard_Real U,V;
1857 gp_Vec d1u,d1v;
1858 gp_Pnt pbid;
1859 gp_Cone Co = Handle(Geom_ConicalSurface)::DownCast(S)->Cone();
1860 ElSLib::Parameters(Co,lin.Location(),U,V);
1861 ElSLib::D1(U,V,Co,pbid,d1u,d1v);
1862 Norm = d1u.Crossed(d1v);
1863 }
1864
1865 IntAna_IntConicQuad ilipl(lin,NeutralPlane,Precision::Angular());
1866 if (ilipl.IsDone() && ilipl.NbPoints() != 0){
1867 if (Oris == TopAbs_REVERSED) {
1868 Norm.Reverse();
1869 }
1870 gp_Ax1 axrot(ilipl.Point(1), Norm.Crossed(Direction));
1871 gp_Lin lires = gp_Lin(gp_Ax1(ilipl.Point(1),Direction)).
1872 Rotated(axrot,Angle);
1873 if (lires.Direction().Dot(lin.Direction()) < 0.) {
1874 lires.Reverse();
1875 }
1876 NewC = new Geom_Line(lires);
1877 }
1878 return NewC;
1879 }
1880
1881
1882 //=======================================================================
1883 //function : Choose
1884 //purpose :
1885 //=======================================================================
1886
Choose(const Draft_IndexedDataMapOfFaceFaceInfo & theFMap,Draft_IndexedDataMapOfEdgeEdgeInfo & theEMap,const TopoDS_Vertex & Vtx,Draft_VertexInfo & Vinf,GeomAdaptor_Curve & AC,GeomAdaptor_Surface & AS)1887 static Standard_Boolean Choose(const Draft_IndexedDataMapOfFaceFaceInfo& theFMap,
1888 Draft_IndexedDataMapOfEdgeEdgeInfo& theEMap,
1889 const TopoDS_Vertex& Vtx,
1890 Draft_VertexInfo& Vinf,
1891 GeomAdaptor_Curve& AC,
1892 GeomAdaptor_Surface& AS)
1893 {
1894 gp_Vec tgref;
1895 Vinf.InitEdgeIterator();
1896
1897 // Find a regular edge with null SecondFace
1898 while (Vinf.MoreEdge()) {
1899 const TopoDS_Edge& E1 = Vinf.Edge();
1900 const Draft_EdgeInfo& Einf1 = theEMap.FindFromKey(E1);
1901 if (Einf1.SecondFace().IsNull()) {
1902 break;
1903 }
1904 else {
1905 GeomAbs_Shape te = BRep_Tool::Continuity(E1,Einf1.FirstFace(),
1906 Einf1.SecondFace());
1907 if (te >= GeomAbs_G1) {
1908 break;
1909 }
1910 }
1911 Vinf.NextEdge();
1912 }
1913 if (!Vinf.MoreEdge()) { // take the first edge
1914 Vinf.InitEdgeIterator();
1915 }
1916
1917 const TopoDS_Edge& Eref = Vinf.Edge();
1918 //const Draft_EdgeInfo& Einf = theEMap(Eref);
1919 Draft_EdgeInfo& Einf = theEMap.ChangeFromKey(Eref);
1920
1921 AC.Load(Einf.Geometry());
1922
1923 Standard_Real f,l,prm;
1924 TopLoc_Location Loc;
1925 Handle(Geom_Curve) C = BRep_Tool::Curve(Eref,Loc,f,l);
1926 C = Handle(Geom_Curve)::DownCast(C->Transformed(Loc.Transformation()));
1927 gp_Pnt ptbid;
1928 //prm = Parameter(C,BRep_Tool::Pnt(Vtx));
1929 Standard_Integer done;
1930 Standard_Real param = Parameter( C, BRep_Tool::Pnt(Vtx), done );
1931 if (done != 0)
1932 {
1933 Handle( Geom_Surface ) S1 = theFMap.FindFromKey(Einf.FirstFace()).Geometry();
1934 Handle( Geom_Surface ) S2 = theFMap.FindFromKey(Einf.SecondFace()).Geometry();
1935 prm = SmartParameter( Einf, BRep_Tool::Tolerance(Eref), BRep_Tool::Pnt(Vtx), done, S1, S2 );
1936 }
1937 else
1938 prm = param;
1939 C->D1(prm,ptbid,tgref);
1940
1941
1942 Vinf.InitEdgeIterator();
1943 while (Vinf.MoreEdge()) {
1944 // Find a non tangent edge
1945 const TopoDS_Edge& Edg = Vinf.Edge();
1946 if (!Edg.IsSame(Eref)) {
1947 //const Draft_EdgeInfo& Einfo = theEMap(Edg);
1948 Draft_EdgeInfo& Einfo = theEMap.ChangeFromKey(Edg);
1949 if (!Einfo.SecondFace().IsNull() &&
1950 BRep_Tool::Continuity(Edg,Einfo.FirstFace(),Einfo.SecondFace())
1951 <= GeomAbs_C0) {
1952 C = BRep_Tool::Curve(Edg,Loc,f,l);
1953 C = Handle(Geom_Curve)::DownCast(C->Transformed(Loc.Transformation()));
1954 //prm = Parameter(C,BRep_Tool::Pnt(Vtx));
1955 Standard_Integer anewdone;
1956 Standard_Real anewparam = Parameter( C, BRep_Tool::Pnt(Vtx), anewdone );
1957 if (anewdone != 0)
1958 {
1959 Handle( Geom_Surface ) S1 = theFMap.FindFromKey(Einfo.FirstFace()).Geometry();
1960 Handle( Geom_Surface ) S2 = theFMap.FindFromKey(Einfo.SecondFace()).Geometry();
1961 prm = SmartParameter( Einfo, BRep_Tool::Tolerance(Edg), BRep_Tool::Pnt(Vtx), anewdone, S1, S2 );
1962 }
1963 else
1964 prm = anewparam;
1965 gp_Vec tg;
1966 C->D1(prm,ptbid,tg);
1967 if (tg.CrossMagnitude(tgref) > Precision::Confusion()) {
1968 break;
1969 }
1970 }
1971 }
1972 Vinf.NextEdge();
1973 }
1974 if (!Vinf.MoreEdge()) {
1975 return Standard_False;
1976 }
1977
1978 const Draft_EdgeInfo& Einf2 = theEMap.FindFromKey(Vinf.Edge());
1979 if (!Einf.SecondFace().IsNull()) {
1980
1981 if (Einf2.FirstFace().IsSame(Einf.FirstFace()) ||
1982 Einf2.FirstFace().IsSame(Einf.SecondFace())) {
1983 AS.Load(theFMap.FindFromKey(Einf2.SecondFace()).Geometry());
1984 }
1985 else {
1986 AS.Load(theFMap.FindFromKey(Einf2.FirstFace()).Geometry());
1987 }
1988 }
1989 else {
1990 if (Einf2.FirstFace().IsSame(Einf.FirstFace())) {
1991 AS.Load(theFMap.FindFromKey(Einf2.SecondFace()).Geometry());
1992 }
1993 else {
1994 AS.Load(theFMap.FindFromKey(Einf2.FirstFace()).Geometry());
1995 }
1996 }
1997 return Standard_True;
1998 }
1999
2000
2001 //=======================================================================
2002 //function : Parameter
2003 //purpose :
2004 //=======================================================================
2005
Parameter(const Handle (Geom_Curve)& C,const gp_Pnt & P,Standard_Integer & done)2006 static Standard_Real Parameter(const Handle(Geom_Curve)& C,
2007 const gp_Pnt& P,
2008 Standard_Integer& done)
2009 {
2010 done = 0;
2011 Handle(Geom_Curve) cbase = C;
2012 Handle(Standard_Type) ctyp = C->DynamicType();
2013 if (ctyp == STANDARD_TYPE(Geom_TrimmedCurve)) {
2014 cbase = Handle(Geom_TrimmedCurve)::DownCast(C)->BasisCurve();
2015 ctyp = cbase->DynamicType();
2016 }
2017 Standard_Real param;
2018 if (ctyp == STANDARD_TYPE(Geom_Line)) {
2019 param = ElCLib::Parameter(Handle(Geom_Line)::DownCast(cbase)->Lin(),P);
2020 }
2021 else if (ctyp == STANDARD_TYPE(Geom_Circle)) {
2022 param = ElCLib::Parameter(Handle(Geom_Circle)::DownCast(cbase)->Circ(),P);
2023 if (Abs(2.*M_PI-param) <=Epsilon(2.*M_PI)) {
2024 param = 0.;
2025 }
2026 }
2027 else if (ctyp == STANDARD_TYPE(Geom_Ellipse)) {
2028 param = ElCLib::Parameter(Handle(Geom_Ellipse)::DownCast(cbase)->Elips(),P);
2029 if (Abs(2.*M_PI-param) <=Epsilon(2.*M_PI)) {
2030 param = 0.;
2031 }
2032 }
2033 else if (ctyp == STANDARD_TYPE(Geom_Parabola)) {
2034 param = ElCLib::Parameter(Handle(Geom_Parabola)::DownCast(cbase)->Parab(),P);
2035 }
2036 else if (ctyp == STANDARD_TYPE(Geom_Hyperbola)) {
2037 param = ElCLib::Parameter(Handle(Geom_Hyperbola)::DownCast(cbase)->Hypr(),P);
2038 }
2039 else {
2040 GeomAdaptor_Curve TheCurve(C);
2041 Extrema_ExtPC myExtPC(P,TheCurve);
2042 if (!myExtPC.IsDone()) {
2043 throw Standard_Failure("Draft_Modification_1::Parameter: ExtremaPC not done.");
2044 }
2045 if (myExtPC.NbExt() >= 1) {
2046 Standard_Real Dist2, Dist2Min = myExtPC.SquareDistance(1);
2047 Standard_Integer j, jmin = 1;
2048 for (j = 2; j <= myExtPC.NbExt(); j++) {
2049 Dist2 = myExtPC.SquareDistance(j);
2050 if (Dist2 < Dist2Min) {
2051 Dist2Min = Dist2;
2052 jmin = j;
2053 }
2054 }
2055 param = myExtPC.Point(jmin).Parameter();
2056 }
2057 else {
2058 Standard_Real dist1_2,dist2_2;
2059 gp_Pnt p1b,p2b;
2060 myExtPC.TrimmedSquareDistances(dist1_2,dist2_2,p1b,p2b);
2061 if (dist1_2 < dist2_2) {
2062 done = -1;
2063 param = TheCurve.FirstParameter();
2064 }
2065 else {
2066 done = 1;
2067 param = TheCurve.LastParameter();
2068 }
2069 }
2070
2071 if (cbase->IsPeriodic()) {
2072 Standard_Real Per = cbase->Period();
2073 Standard_Real Tolp = Precision::Parametric(Precision::Confusion());
2074 if (Abs(Per-param) <= Tolp) {
2075 param = 0.;
2076 }
2077 }
2078 }
2079 return param;
2080 }
2081
2082 //=======================================================================
2083 //function : SmartParameter
2084 //purpose :
2085 //=======================================================================
2086
SmartParameter(Draft_EdgeInfo & Einf,const Standard_Real EdgeTol,const gp_Pnt & Pnt,const Standard_Integer sign,const Handle (Geom_Surface)& S1,const Handle (Geom_Surface)& S2)2087 static Standard_Real SmartParameter(Draft_EdgeInfo& Einf,
2088 const Standard_Real EdgeTol,
2089 const gp_Pnt& Pnt,
2090 const Standard_Integer sign,
2091 const Handle(Geom_Surface)& S1,
2092 const Handle(Geom_Surface)& S2)
2093 {
2094 Handle( Geom2d_Curve ) NewC2d;
2095 Standard_Real Tol = Precision::Confusion();
2096 Standard_Real Etol = EdgeTol;
2097
2098 Handle( Geom2d_Curve ) pcu1 = Einf.FirstPC();
2099 Handle( Geom2d_Curve ) pcu2 = Einf.SecondPC();
2100
2101 if (pcu1.IsNull())
2102 {
2103 Handle( Geom_Curve ) theCurve = Einf.Geometry();
2104 pcu1 = GeomProjLib::Curve2d( theCurve, theCurve->FirstParameter(), theCurve->LastParameter(), S1, Etol );
2105 Einf.ChangeFirstPC() = pcu1;
2106 }
2107 if (pcu2.IsNull())
2108 {
2109 Handle( Geom_Curve ) theCurve = Einf.Geometry();
2110 pcu2 = GeomProjLib::Curve2d( theCurve, theCurve->FirstParameter(), theCurve->LastParameter(), S2, Etol );
2111 Einf.ChangeSecondPC() = pcu2;
2112 }
2113
2114 GeomAPI_ProjectPointOnSurf Projector( Pnt, S1 );
2115 Standard_Real U, V;
2116 Projector.LowerDistanceParameters( U, V );
2117
2118 NewC2d = Einf.FirstPC();
2119 if (NewC2d->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve))
2120 NewC2d = (Handle(Geom2d_TrimmedCurve)::DownCast(NewC2d))->BasisCurve();
2121
2122 gp_Pnt2d P2d( U, V );
2123 Geom2dAPI_ProjectPointOnCurve Projector2d( P2d, NewC2d );
2124 if (Projector2d.NbPoints() == 0 || Projector2d.LowerDistance() > Tol)
2125 {
2126 Handle( Geom2d_BSplineCurve ) BCurve;
2127 if (NewC2d->DynamicType() != STANDARD_TYPE(Geom2d_BSplineCurve))
2128 BCurve = Geom2dConvert::CurveToBSplineCurve( NewC2d );
2129 else
2130 BCurve = Handle( Geom2d_BSplineCurve )::DownCast( NewC2d );
2131 if (sign == -1)
2132 {
2133 TColgp_Array1OfPnt2d PntArray( 1, 2 );
2134 PntArray(1) = P2d;
2135 PntArray(2) = BCurve->Pole(1);
2136 Handle( Geom2d_BezierCurve ) Patch = new Geom2d_BezierCurve( PntArray );
2137 Geom2dConvert_CompCurveToBSplineCurve Concat( BCurve, Convert_QuasiAngular );
2138 Concat.Add( Patch, Tol, Standard_False );
2139 BCurve = Concat.BSplineCurve();
2140 }
2141 else
2142 {
2143 TColgp_Array1OfPnt2d PntArray( 1, 2 );
2144 PntArray(1) = BCurve->Pole( BCurve->NbPoles() );
2145 PntArray(2) = P2d;
2146 Handle( Geom2d_BezierCurve ) Patch = new Geom2d_BezierCurve( PntArray );
2147 Geom2dConvert_CompCurveToBSplineCurve Concat( BCurve, Convert_QuasiAngular );
2148 Concat.Add( Patch, Tol, Standard_True );
2149 BCurve = Concat.BSplineCurve();
2150 }
2151 NewC2d = BCurve;
2152 }
2153 Einf.ChangeFirstPC() = NewC2d;
2154 Handle( Geom2dAdaptor_Curve ) hcur = new Geom2dAdaptor_Curve( NewC2d );
2155 Handle( GeomAdaptor_Surface ) hsur = new GeomAdaptor_Surface( S1 );
2156 Adaptor3d_CurveOnSurface cons( hcur, hsur );
2157 Handle( Adaptor3d_CurveOnSurface ) hcons = new Adaptor3d_CurveOnSurface( cons );
2158 Handle( GeomAdaptor_Surface ) hsur2 = new GeomAdaptor_Surface( S2 );
2159 Handle(ProjLib_HCompProjectedCurve) HProjector = new ProjLib_HCompProjectedCurve (hsur2, hcons, Tol, Tol);
2160 Standard_Real Udeb, Ufin;
2161 HProjector->Bounds(1, Udeb, Ufin);
2162 Standard_Integer MaxSeg = 20 + HProjector->NbIntervals(GeomAbs_C3);
2163 Approx_CurveOnSurface appr(HProjector, hsur2, Udeb, Ufin, Tol);
2164 appr.Perform(MaxSeg, 10, GeomAbs_C1, Standard_False, Standard_False);
2165 Einf.ChangeSecondPC() = appr.Curve2d();
2166 Einf.ChangeGeometry() = appr.Curve3d();
2167 Einf.SetNewGeometry( Standard_True );
2168
2169 if (sign == -1)
2170 return Einf.Geometry()->FirstParameter();
2171 else
2172 return Einf.Geometry()->LastParameter();
2173
2174 }
2175
2176 //=======================================================================
2177 //function : Orientation
2178 //purpose :
2179 //=======================================================================
2180
Orientation(const TopoDS_Shape & S,const TopoDS_Face & F)2181 static TopAbs_Orientation Orientation(const TopoDS_Shape& S,
2182 const TopoDS_Face& F)
2183 {
2184 //
2185 // change porting NT
2186 //
2187 TopExp_Explorer expl ;
2188 expl.Init(S,
2189 TopAbs_FACE) ;
2190 while (expl.More()) {
2191 if (TopoDS::Face(expl.Current()).IsSame(F)) {
2192 return expl.Current().Orientation();
2193 }
2194 expl.Next();
2195 }
2196 return TopAbs_FORWARD;
2197 }
2198
2199
2200 //=======================================================================
2201 //function : FindRotation
2202 //purpose :
2203 //=======================================================================
2204
FindRotation(const gp_Pln & Pl,const TopAbs_Orientation Oris,const gp_Dir & Direction,const Standard_Real Angle,const gp_Pln & NeutralPlane,gp_Ax1 & Axe,Standard_Real & theta)2205 static Standard_Boolean FindRotation(const gp_Pln& Pl,
2206 const TopAbs_Orientation Oris,
2207 const gp_Dir& Direction,
2208 const Standard_Real Angle,
2209 const gp_Pln& NeutralPlane,
2210 gp_Ax1& Axe,
2211 Standard_Real& theta)
2212 {
2213 IntAna_QuadQuadGeo i2pl(Pl,NeutralPlane,
2214 Precision::Angular(),Precision::Confusion());
2215
2216 if (i2pl.IsDone() && i2pl.TypeInter() == IntAna_Line) {
2217 gp_Lin li = i2pl.Line(1);
2218 // Try to turn around this line
2219 gp_Dir nx = li.Direction();
2220 gp_Dir ny = Pl.Axis().Direction().Crossed(nx);
2221 Standard_Real a = Direction.Dot(nx);
2222 if (Abs(a) <=1-Precision::Angular()) {
2223 Standard_Real b = Direction.Dot(ny);
2224 Standard_Real c = Direction.Dot(Pl.Axis().Direction());
2225 Standard_Boolean direct(Pl.Position().Direct());
2226 if ((direct && Oris == TopAbs_REVERSED) ||
2227 (!direct && Oris == TopAbs_FORWARD)) {
2228 b = -b;
2229 c = -c;
2230 }
2231 Standard_Real denom = Sqrt(1-a*a);
2232 Standard_Real Sina = Sin(Angle);
2233 if (denom>Abs(Sina)) {
2234 Standard_Real phi = ATan2(b/denom,c/denom);
2235 Standard_Real theta0 = ACos(Sina/denom);
2236 theta = theta0 - phi;
2237 if (Cos(theta) <0.) {
2238 theta = -theta0 -phi;
2239 }
2240 // modified by NIZHNY-EAP Tue Nov 16 15:51:38 1999 ___BEGIN___
2241 while (Abs(theta)>M_PI) {
2242 theta = theta + M_PI*(theta<0 ? 1 : -1);
2243 }
2244 // modified by NIZHNY-EAP Tue Nov 16 15:53:32 1999 ___END___
2245 Axe = li.Position();
2246 return Standard_True;
2247 }
2248 }
2249 }
2250 return Standard_False;
2251 }
2252
2253