0024530: TKMesh - remove unused package IntPoly
[occt.git] / src / Draft / Draft_Modification_1.cxx
CommitLineData
b311480e 1// Created on: 1994-12-02
2// Created by: Jacques GOUSSARD
3// Copyright (c) 1994-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
973c2be1 8// This library is free software; you can redistribute it and / or modify it
9// under the terms of the GNU Lesser General Public 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.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
17#include <Draft_Modification.jxx>
18
19#include <BRep_Tool.hxx>
20#include <BRep_Builder.hxx>
21
22#include <BRepLib_MakeFace.hxx>
23
24#include <TopLoc_Location.hxx>
25#include <TopExp_Explorer.hxx>
26#include <TopTools_ListIteratorOfListOfShape.hxx>
27
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>
36
37#include <Geom_Surface.hxx>
38#include <Geom_RectangularTrimmedSurface.hxx>
39
40
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>
56
57#include <gp_Vec.hxx>
58#include <gp_Lin.hxx>
59#include <gp_Pln.hxx>
60#include <gp_Circ.hxx>
61#include <gp_Elips.hxx>
62#include <gp_Parab.hxx>
63#include <gp_Hypr.hxx>
64
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>
70
71#include <Extrema_ExtPC.hxx>
72#include <BRepExtrema_ExtPC.hxx>
73#include <BRepExtrema_ExtCF.hxx>
74
75#include <Standard_DomainError.hxx>
76#include <Standard_Failure.hxx>
77#include <Standard_NotImplemented.hxx>
78
79#include <TopTools_MapOfShape.hxx>
80#include <TopTools_MapIteratorOfMapOfShape.hxx>
81
82#include <gp.hxx>
83#include <Precision.hxx>
84#include <ElCLib.hxx>
85#include <ElSLib.hxx>
86#include <BRepTools.hxx>
87#include <TopoDS.hxx>
88#include <TopExp.hxx>
89
90#include <GeomAdaptor_HCurve.hxx>
91#include <GeomAdaptor_HSurface.hxx>
92#include <GeomAPI_ProjectPointOnSurf.hxx>
93
94#include <GeomAPI_ProjectPointOnCurve.hxx>
95
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>
102
103#include <GeomProjLib.hxx>
104#include <TColgp_Array1OfPnt2d.hxx>
105#include <Geom2d_BezierCurve.hxx>
106#include <Geom2dConvert_CompCurveToBSplineCurve.hxx>
107
108#include <Adaptor3d_HCurveOnSurface.hxx>
109#include <ProjLib_CompProjectedCurve.hxx>
110#include <ProjLib_HCompProjectedCurve.hxx>
111#include <Approx_CurveOnSurface.hxx>
112
113#include <GeomConvert_CompCurveToBSplineCurve.hxx>
114
115
116static Standard_Boolean Choose(const Draft_DataMapOfFaceFaceInfo&,
117 Draft_DataMapOfEdgeEdgeInfo&,
118 const TopoDS_Vertex&,
119 Draft_VertexInfo&,
120 GeomAdaptor_Curve&,
121 GeomAdaptor_Surface&);
122
123static Standard_Real Parameter(const Handle(Geom_Curve)&,
124 const gp_Pnt&,
125 Standard_Integer&);
126
127static Standard_Real SmartParameter(Draft_EdgeInfo&,
128 const Standard_Real EdgeTol,
129 const gp_Pnt&,
130 const Standard_Integer,
131 const Handle(Geom_Surface)&,
132 const Handle(Geom_Surface)&);
133
134static TopAbs_Orientation Orientation(const TopoDS_Shape&,
135 const TopoDS_Face&);
136
137static Standard_Boolean FindRotation(const gp_Pln&,
138 const TopAbs_Orientation,
139 const gp_Dir&,
140 const Standard_Real,
141 const gp_Pln&,
142 gp_Ax1&,
143 Standard_Real&);
144
145
146//=======================================================================
147//function : InternalAdd
148//purpose :
149//=======================================================================
150
151Standard_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)
156{
157
158 if (myFMap.IsBound(F)) {
159 return (badShape.IsNull());
160 }
161
162 TopAbs_Orientation oris = Orientation(myShape,F);
163 TopLoc_Location Lo;
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();
170 }
171 Handle(Geom_Surface) NewS;
172 Handle(Geom_Circle) theCircle;
173
174 Standard_Boolean postponed = (Flag == Standard_False);
175 if (postponed) {
176 Handle(Standard_Type) typS = S->DynamicType();
177 if (typS == STANDARD_TYPE(Geom_CylindricalSurface) ||
178 typS == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
179 gp_Circ Cir;
180 if (typS == STANDARD_TYPE(Geom_CylindricalSurface)) {
181 gp_Cylinder cyl =
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());
187 }
188 else {
189 Handle(Geom_Curve) Cbas =
190 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(S)->BasisCurve();
191 gp_Dir theDirextr =
192 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(S)->Direction();
193
194 if (Cbas->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
195 Cbas = Handle(Geom_TrimmedCurve)::DownCast(Cbas)->BasisCurve();
196 }
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())) {
201 badShape = F;
202 errStat = Draft_FaceRecomputation;
203 return Standard_False;
204 }
205 }
206 else {
207 badShape = F;
208 errStat = Draft_FaceRecomputation;
209 return Standard_False;
210 }
211
212 gp_Ax3 Axis = NeutralPlane.Position();
213 Standard_Real L =
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;
218 Cir.Translate(VV);
219 }
220
221 theCircle = new Geom_Circle(Cir);
222
223 }
224 else {
225 postponed = Standard_False;
226 }
227 }
228
229
230 if (!postponed) {
231 NewS = NewSurface(S,oris,Direction,Angle,NeutralPlane);
232 if (NewS.IsNull()) {
233 badShape = F;
234 errStat = Draft_FaceRecomputation;
235 return Standard_False;
236 }
0d969553 237 // To avoid some problems with infinite restrictions
7fd59977 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;
249 }
250 else {
251 gp_Cone Co = Handle(Geom_ConicalSurface)::DownCast(NewS)->Cone();
252 Standard_Real Vapex = - Co.RefRadius()/Sin(Co.SemiAngle());
0d969553 253 if (vmin < Vapex) { // vmax should not exceed Vapex
7fd59977 254 if (vmax + deltav > Vapex) {
255 vmax = Vapex;
256 vmin = vmin - 10.*(vmax - vmin);
0d969553 257 // JAG debug to avoid apex
7fd59977 258 vmax = vmax-Precision::Confusion();
259 }
260 else {
261 vmin = vmin - deltav;
262 vmax = vmax + deltav;
263 }
264 }
0d969553 265 else { // Vapex <= vmin < vmax
7fd59977 266 if (vmin - deltav < Vapex) {
267 vmin = Vapex;
268 vmax = vmax + 10.*(vmax - vmin);
0d969553 269 // JAG debug to avoid apex
7fd59977 270 vmin = vmin+Precision::Confusion();
271 }
272 else {
273 vmin = vmin - deltav;
274 vmax = vmax + deltav;
275 }
276 }
277 }
c6541a0c 278 NewS = new Geom_RectangularTrimmedSurface(NewS,0.,2.*M_PI,vmin,vmax);
7fd59977 279 }
280 }
281 }
282
283 if (postponed || S != NewS) {
284 Draft_FaceInfo FI(NewS,Standard_True);
285 FI.RootFace(curFace);
286 myFMap.Bind(F,FI);
287 if (postponed) {
288 myFMap(F).ChangeCurve() = theCircle;
289 }
290 }
291
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;
299 TopoDS_Face OtherF;
300 // if (BRep_Tool::IsClosed(edg,F)) {
301 if (BRepTools::IsReallyClosed(edg,F)) {
302 addedg = Standard_True;
303 addface = Standard_False;
304 }
305 else {
0d969553 306 // Find the other face containing the edge.
7fd59977 307 TopTools_ListIteratorOfListOfShape it;
308 it.Initialize(myEFMap.FindFromKey(edg));
309 Standard_Integer nbother = 0;
310 while (it.More()) {
311 if (!it.Value().IsSame(F)) {
312 if (OtherF.IsNull()) {
313 OtherF = TopoDS::Face(it.Value());
314 }
315 nbother++;
316 }
317 it.Next();
318 }
319 if (nbother >=2) {
320 badShape = edg;
321 errStat = Draft_EdgeRecomputation;
322 }
323 else if (! OtherF.IsNull() &&
324 BRep_Tool::Continuity(edg,F,OtherF) >= GeomAbs_G1) {
325 addface= Standard_True;
326 addedg = Standard_True;
327 }
0d969553 328 else if (nbother == 0) {
7fd59977 329 // badShape = F;
330 }
331 }
332 if (addedg) {
333 if (postponed) {
334 myFMap(F).Add(OtherF);
335 }
336 Standard_Real f,l;
337 TopLoc_Location L;
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();
342 }
343 Handle(Geom_Curve) NewC;
344 Draft_EdgeInfo EInf(Standard_True);
345 if(postponed) {
346 EInf.Add(F);
347 EInf.Add(OtherF);
348
0d969553 349 // find fixed point
7fd59977 350 Handle(Geom_Line) aLocalGeom = Handle(Geom_Line)::DownCast(C);
351 if (aLocalGeom.IsNull()) {
352 badShape = edg;
353 errStat = Draft_EdgeRecomputation;
354 }
355 else {
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));
360 }
361 else {
362 badShape = edg;
363 errStat = Draft_EdgeRecomputation;
364 }
365 }
366 }
367 else {
368 NewC = NewCurve(C,S,oris,Direction,Angle,NeutralPlane, Flag);
369 if (NewC.IsNull()) {
370 badShape = edg;
371 errStat = Draft_EdgeRecomputation;
372 }
373 }
374
375 Handle(Geom_TrimmedCurve) T = Handle(Geom_TrimmedCurve)::DownCast(NewC);
376 if (!T.IsNull()) NewC = T->BasisCurve();
377 EInf.ChangeGeometry() = NewC;
378
379 EInf.RootFace(curFace);
380 myEMap.Bind(edg,EInf);
381 MapOfE.Add(edg);
382 if (addface) {
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();
389 }
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) {
395 myFMap.UnBind(F);
396 TopTools_MapIteratorOfMapOfShape itm(MapOfE);
397 for ( ; itm.More(); itm.Next())
398 myEMap.UnBind(TopoDS::Edge(itm.Key()));
399 }
400 }
401 }
402 InternalAdd(OtherF,Direction,Angle,NeutralPlane, Fl);
403 }
404 }
405 }
406 expl.Next();
407 }
408 return (badShape.IsNull());
409}
410
411
412//=======================================================================
413//function : Propagate
414//purpose :
415//=======================================================================
416
417Standard_Boolean Draft_Modification::Propagate ()
418{
419
420 if (!badShape.IsNull()) return Standard_False;
421
422 Draft_DataMapIteratorOfDataMapOfFaceFaceInfo itf(myFMap);
423
0d969553 424 // Set all edges and vertices of modified faces
7fd59977 425 TopoDS_Face F;
426 TopoDS_Edge E;
427 TopoDS_Vertex V;
428 TopExp_Explorer editer;
429 TopExp_Explorer vtiter;
430
431 while (itf.More()) {
432 const TopoDS_Face& Fc = itf.Key();
433
434 // Exploration of the edges of the face
435 editer.Init(Fc,TopAbs_EDGE);
436 while (editer.More()) {
437 E = TopoDS::Edge(editer.Current());
438
439 if (!myEMap.IsBound(E)) {
440 Draft_EdgeInfo EInf(Standard_True);
441 myEMap.Bind(E,EInf);
442 }
443 myEMap(E).Add(Fc);
444
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;
451 myVMap.Bind(V,VInf);
452 }
453
454 myVMap(V).Add(E);
455 myVMap(V).ChangeParameter(E) = BRep_Tool::Parameter(V, E);
456 vtiter.Next();
457 }
458 editer.Next();
459 }
460 itf.Next();
461 }
462
463
464 TopExp_Explorer anc;
465 Standard_Boolean found;
466
0d969553 467 // Set edges containing modified vertices.
7fd59977 468
469 Draft_DataMapIteratorOfDataMapOfVertexVertexInfo itv(myVMap);
470
471 while (itv.More()) {
472 const TopoDS_Vertex& Vt = itv.Key();
473
474 // Exploration of the ancestors of the vertex
475 anc.Init(myShape,TopAbs_EDGE);
476
477 while (anc.More()) {
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;
484 break;
485 }
486 vtiter.Next();
487 }
488 if (found) {
489 if (!myEMap.IsBound(E)) {
490 Draft_EdgeInfo EInf(Standard_False);
491 myEMap.Bind(E,EInf);
492 }
493 myVMap(Vt).Add(E);
494 myVMap(Vt).ChangeParameter(E) = BRep_Tool::Parameter(Vt, E);
495 }
496 anc.Next();
497 }
498 itv.Next();
499 }
500
501
0d969553 502 // Set faces containing modified edges
7fd59977 503
504 Draft_DataMapIteratorOfDataMapOfEdgeEdgeInfo ite(myEMap);
505
506 while (ite.More()) {
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)) {
512 TopLoc_Location L;
513 Handle(Geom_Surface) S = BRep_Tool::Surface(F,L);
514 Handle(Geom_Surface) NewS =
515 Handle(Geom_Surface)::DownCast(S->Transformed(L.Transformation()));
516
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;
527 NewS =
c6541a0c 528 new Geom_RectangularTrimmedSurface(NewS,0.,2.*M_PI,vmin,vmax);
7fd59977 529 }
530 }
531
532 Draft_FaceInfo FInf(NewS,Standard_False);
533 myFMap.Bind(F,FInf);
534 }
535 myEMap(Ed).Add(F);
536 }
537 ite.Next();
538 }
539
0d969553 540 // Try to add faces for free borders...
7fd59977 541 // JAG 09.11.95
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()) {
547
548 TopLoc_Location Loc;
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;
553
554 Standard_Real f,l;
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();
559 }
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);
564 }
565 else if (C->DynamicType() == STANDARD_TYPE(Geom_Line)) {
566 gp_Ax1 axis;
567 if (S1->DynamicType()== STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
568 axis = Handle(Geom_ElementarySurface)::DownCast
569 (Handle(Geom_RectangularTrimmedSurface)::DownCast(S1)->
570 BasisSurface())->Axis();
571 }
572 else {
573 axis = Handle(Geom_ElementarySurface)::DownCast(S1)->Axis();
574 }
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()));
578
579 }
580 else {
581 badShape = TopoDS::Edge(ite.Key());
582 errStat = Draft_EdgeRecomputation;
0d969553 583 break; // leave from for
7fd59977 584 }
585 }
0d969553 586 else { // on the plane
7fd59977 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())) {
592 break;
593 }
594 }
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()))) {
602 break;
603 }
604 }
605 }
606 if (Vinf.MoreEdge()) {
607 Handle(Geom_Curve) C2 = BRep_Tool::Curve(Vinf.Edge(), Loc,f,l);
608 Handle(GeomAdaptor_HCurve) HCur;
609 gp_Vec Direc;
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();
614 }
615 if (C->DynamicType() == STANDARD_TYPE(Geom_Line)) {
616 Direc = Handle(Geom_Line)::DownCast(C)->Lin().Direction();
617 HCur = new GeomAdaptor_HCurve(C2);
618
619 }
620 else if (C2->DynamicType() == STANDARD_TYPE(Geom_Line)) {
621 Direc = Handle(Geom_Line)::DownCast(C2)->Lin().Direction();
622 HCur = new GeomAdaptor_HCurve(C);
623 }
624 else {
625 badShape = TopoDS::Edge(ite.Key());
626 errStat = Draft_EdgeRecomputation;
0d969553 627 break; // leave from while
7fd59977 628 }
629 Adaptor3d_SurfaceOfLinearExtrusion SLE(HCur,Direc);
630 switch(SLE.GetType()){
631
632 case GeomAbs_Plane :
633 {
634 S2 = new Geom_Plane(SLE.Plane());
635 }
636 break;
637 case GeomAbs_Cylinder :
638 {
639 S2 = new Geom_CylindricalSurface(SLE.Cylinder());
640 }
641 break;
642 default :
643 {
644 S2 = new Geom_SurfaceOfLinearExtrusion(HCur->ChangeCurve().
645 Curve(),
646 Direc);
647 }
648 break;
649 }
650
651 }
652 else {
653 badShape = TopoDS::Edge(ite.Key());
654 errStat = Draft_EdgeRecomputation;
0d969553 655 break; // leave from while
7fd59977 656 }
657 break;
658 }
659 anewitv.Next();
660 }
661 }
662
663 if (badShape.IsNull()) {
664 BRep_Builder B;
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);
670 }
671 else {
0d969553 672 break; // leave from for
7fd59977 673 }
674 // Fin JAG 09.11.95
675 }
676 }
677 return (badShape.IsNull());
678}
679
680
681
682
683//=======================================================================
684//function : Perform
685//purpose :
686//=======================================================================
687
688void Draft_Modification::Perform ()
689{
690 if (!badShape.IsNull()) Standard_ConstructionError::Raise();
691
692 if (!myComp) {
693 myComp = Standard_True;
694 if (!Propagate()) {
695 return;
696 }
697
0d969553 698 // Calculate eventual faces
7fd59977 699
700 Draft_DataMapIteratorOfDataMapOfFaceFaceInfo itf(myFMap);
701 while (itf.More()) {
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();
706
707 if (F1.IsNull() || F2.IsNull()) {
708 errStat = Draft_FaceRecomputation;
709 badShape = TopoDS::Face(itf.Key());
710 return;
711 }
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());
717 return;
718 }
719 if (S1->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
720 S1 = Handle(Geom_RectangularTrimmedSurface)::
721 DownCast(S1)->BasisSurface();
722 }
723 if (S2->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
724 S2 = Handle(Geom_RectangularTrimmedSurface)::
725 DownCast(S2)->BasisSurface();
726 }
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());
732 return;
733 }
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());
741 return;
742 }
743
744 gp_Dir extrdir = i2p.Line(1).Direction();
745
0d969553 746 // Preserve the same direction as the base face
7fd59977 747 Handle(Geom_Surface) RefSurf =
748 BRep_Tool::Surface(TopoDS::Face(itf.Key()));
749 if (RefSurf->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
750 RefSurf =
751 Handle(Geom_RectangularTrimmedSurface)::DownCast(RefSurf)
752 ->BasisSurface();
753 }
754 gp_Dir DirRef;
755
756 if ( RefSurf->DynamicType() == STANDARD_TYPE(Geom_CylindricalSurface)) {
757 gp_Ax3 AxeRef =
758 Handle(Geom_CylindricalSurface)::DownCast(RefSurf)
759 ->Cylinder().Position();
760 DirRef = AxeRef.Direction();
761 }
762 else if (RefSurf->DynamicType() ==
763 STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
764 DirRef =
765 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(RefSurf)
766 ->Direction();
767 }
768
769 if (extrdir.Dot(DirRef) < 0.) extrdir.Reverse();
770
0d969553
Y
771 // it is possible to accelerate speed by storing the info during
772 // InternalAdd --> modification of FaceInfo to preserve the circle
7fd59977 773
774 Handle(Geom_Circle) CCir =
775 Handle(Geom_Circle)::DownCast(Finf.Curve());
776 Handle(Geom_Surface) NewS =
777 new Geom_SurfaceOfLinearExtrusion(CCir, extrdir);
778
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;
786 }
787
0d969553 788 // very temporary
7fd59977 789 else {
790 vmax = 300;
791 vmin = -300;
792 }
793
c6541a0c 794 NewS = new Geom_RectangularTrimmedSurface(NewS,0.,1.9*M_PI,vmin,vmax);
7fd59977 795 Finf.ChangeGeometry() = NewS;
796 }
797 itf.Next();
798 }
799
0d969553 800 // Calculate new edges.
7fd59977 801
802 Handle(Geom_Surface) S1,S2;
803 Handle(Geom_Curve) C, newC;
804 Standard_Real f,l;
805 TopLoc_Location L;
806 Draft_DataMapIteratorOfDataMapOfEdgeEdgeInfo ite(myEMap);
807
808 while (ite.More()) {
809 Draft_EdgeInfo& Einf = myEMap(ite.Key());
810
811 const TopoDS_Edge& theEdge = TopoDS::Edge(ite.Key());
812
813 C = BRep_Tool::Curve(theEdge,L,f,l);
814 C = Handle(Geom_Curve)::DownCast(C->Transformed(L.Transformation()));
815
816 if (Einf.NewGeometry() && Einf.Geometry().IsNull()) {
817 gp_Pnt ptfixe;
818 if (!Einf.IsTangent(ptfixe)) {
819 const TopoDS_Face& FirstFace = Einf.FirstFace();
820 const TopoDS_Face& SecondFace = Einf.SecondFace();
821
822 S1 = myFMap(FirstFace).Geometry();
823 S2 = myFMap(SecondFace).Geometry();
824
825 Standard_Integer detrompeur = 0;
826
0d969553 827 // Return FirstVertex and the tangent at this point.
7fd59977 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());
833 gp_Pnt pfv, plv;
834 gp_Vec d1fv,d1lv, newd1;
835 C->D1(prmfv,pfv,d1fv);
836 C->D1(prmlv,plv,d1lv);
837
838 Standard_Real TolF1 = BRep_Tool::Tolerance (FirstFace);
839 Standard_Real TolF2 = BRep_Tool::Tolerance (SecondFace);
840
0d969553 841 //Pass the tolerance of the face to project
7fd59977 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);
846
847 if (proj1.IsDone () && proj2.IsDone ()) {
848 if(proj1.LowerDistance()<= Precision::Confusion() &&
849 proj2.LowerDistance()<= Precision::Confusion()) {
850 detrompeur = 1;
851 }
852 }
853
854 if (proj3.IsDone () && proj4.IsDone ()) {
855 if(proj3.LowerDistance() <= Precision::Confusion() &&
856 proj4.LowerDistance() <= Precision::Confusion()) {
857 detrompeur = 2;
858 }
859 }
860
861 gp_Dir TheDirExtr;
862 gp_Ax3 Axis;
863 Handle(Geom_Curve) TheNewCurve;
864 Standard_Boolean KPart = Standard_False;
865
866 if ( S1->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
867 S1 = Handle(Geom_RectangularTrimmedSurface)::
868 DownCast(S1)->BasisSurface();
869 }
870 if ( S2->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
871 S2 = Handle(Geom_RectangularTrimmedSurface)::
872 DownCast(S2)->BasisSurface();
873 }
874
0d969553 875 Standard_Boolean PC1 = Standard_True; // KPart on S1
7fd59977 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();
884 }
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();
894 }
895 Handle(Geom_Circle) aCirc ;
0d969553 896 if ( KPart) { // very temporary on circles !!!
7fd59977 897 aCirc = Handle(Geom_Circle)::DownCast(TheNewCurve);
898 if (aCirc.IsNull())
899 KPart = Standard_False;
900 else
901 {
902 gp_Dir AxofCirc = aCirc->Position().Direction();
903 if (AxofCirc.IsParallel(Axis.Direction(),Precision::Angular()))
904 KPart = Standard_True;
905 else
906 KPart = Standard_False;
907 }
908 }
909
910 Standard_Integer imin;
911 GeomInt_IntSS i2s;
912 if ( KPart) {
0d969553 913 // direct calculation of NewC
7fd59977 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));
0d969553 920 // it is possible to calculate PCurve
7fd59977 921 Handle(Geom2d_Line) L2d
922 = new Geom2d_Line(gp_Pnt2d(0.,aLocalReal/Cos),
923 gp::DX2d());
924
925 if ( PC1)
926 Einf.ChangeFirstPC() = L2d;
927 else
928 Einf.ChangeSecondPC() = L2d;
929 }
930 else {
931 S1 = myFMap(Einf.FirstFace()).Geometry();
932 S2 = myFMap(Einf.SecondFace()).Geometry();
933
0d969553
Y
934
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.
7fd59977 939 i2s.Perform(S1,S2,Precision::Confusion(),
940 Standard_True,Standard_False,Standard_False);
941
942 if (!i2s.IsDone() || i2s.NbLines() <= 0) {
943 errStat = Draft_EdgeRecomputation;
944 badShape = TopoDS::Edge(ite.Key());
945 return;
946 }
947
948 Standard_Real Dist2, Dist2Min = 0., Glob2Min = RealLast();
949 GeomAdaptor_Curve TheCurve;
950
951 Standard_Integer i,j; //,jmin;
952
953 if (i2s.Line(1)->DynamicType() != STANDARD_TYPE(Geom_BSplineCurve))
954 {
955 imin = 0;
956 for (i=1; i<= i2s.NbLines(); i++) {
957 TheCurve.Load(i2s.Line(i));
958 Extrema_ExtPC myExtPC(pfv,TheCurve);
959
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();
965 }
08cd2f6b 966 if(myExtPC.NbExt() == 2 && Dist2Min > Precision::SquareConfusion()) {
0d969553
Y
967 //to avoid incorrectly choosing the image
968 //of the first vertex of the initial edge
7fd59977 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();
974 }
975 else if(d2_2 > 1.21*d1_2) {
976 Dist2Min = myExtPC.SquareDistance(1);
977 locpmin = myExtPC.Point(1).Parameter();
978 }
979 else {
980 Standard_Real pfvpar = myExtPC.Point(1).Parameter();
981 Standard_Real plvpar = myExtPC.Point(2).Parameter();
982 newC = i2s.Line(i);
983
984 gp_Pnt pfvprim, plvprim;
985
986 newC->D0(pfvpar,pfvprim);
987 newC->D0(plvpar,plvprim);
988
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();
995 theSurf = S1;
996
997 }
998 else if(detrompeur == 2) {
999 if(S2->DynamicType() ==
1000 STANDARD_TYPE(Geom_RectangularTrimmedSurface))
1001 S2 = Handle(Geom_RectangularTrimmedSurface)::
1002 DownCast(S2)->BasisSurface();
1003 theSurf = S2;
1004 }
1005 if(detrompeur != 0 && detrompeur != 4) {
1d47d8d0 1006 Standard_Real ul = 0., vl = 0., uf = 0., vf = 0.;
1007 Standard_Real ufprim = 0., ulprim = 0., vfprim = 0., vlprim = 0.;
7fd59977 1008
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);
1015 }
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);
1024 }
1025 else detrompeur = 4;
1026
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();
1034 }
1035 }
1036 }
1037 }
1038 }
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) {
1045 Dist2Min = Dist2;
1046 locpmin = myExtPC.Point(j).Parameter();
1047 }
1048 }
1049 }
1050 else if(myExtPC.NbExt() < 1){
1051 Standard_Real dist1_2,dist2_2;
1052 gp_Pnt p1b,p2b;
1053 myExtPC.TrimmedSquareDistances(dist1_2,dist2_2,p1b,p2b);
1054 if (dist1_2 < dist2_2) {
1055 Dist2Min = dist1_2;
1056 locpmin = TheCurve.FirstParameter();
1057 }
1058 else {
1059 Dist2Min = dist2_2;
1060 locpmin = TheCurve.LastParameter();
1061 }
1062 }
1063
1064 if (Dist2Min < Glob2Min) {
1065 Glob2Min = Dist2Min;
1066 imin = i;
1067 pmin = locpmin;
1068 }
1069 }
1070 }
1071 if (imin == 0) {
1072 errStat = Draft_EdgeRecomputation;
1073 badShape = TopoDS::Edge(ite.Key());
1074 return;
1075 }
1076
1077 newC = i2s.Line(imin);
1078
1079 newC->D1(pmin,pfv,newd1);
1080 Standard_Boolean YaRev = d1fv.Dot(newd1) <0.;
1081
1082 if (YaRev)
1083 newC->Reverse();
1084
1085 if (i2s.HasLineOnS1(imin)) {
1086 Einf.ChangeFirstPC() = i2s.LineOnS1(imin);
1087 if ( YaRev)
1088 Einf.ChangeFirstPC()->Reverse();
1089 }
1090
1091 if (i2s.HasLineOnS2(imin)) {
1092 Einf.ChangeSecondPC() = i2s.LineOnS2(imin);
1093 if ( YaRev)
1094 Einf.ChangeSecondPC()->Reverse();
1095 }
1096 } // if (i2s.Line(1)->DynamicType() != STANDARD_TYPE(Geom_BSplineCurve))
1097 else // i2s.Line(1) is BSplineCurve
1098 {
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))
1103 {
1104 for (i = 1; i <= i2s.NbLines(); i++)
1105 {
1106 Handle( Geom_Curve ) aCurve = i2s.Line(i);
1107 gp_Pnt Pnt = aCurve->Value( aCurve->FirstParameter() );
1108 GeomAPI_ProjectPointOnSurf projector( Pnt, S1, Precision::Confusion() );
1109 Standard_Real U, V;
1110 projector.LowerDistanceParameters( U, V );
c6541a0c 1111 if (Abs(U) <= Precision::Confusion() || Abs(U-2.*M_PI) <= Precision::Confusion())
7fd59977 1112 Candidates.Append( aCurve );
1113 else
1114 {
1115 Pnt = aCurve->Value( aCurve->LastParameter() );
1116 projector.Init( Pnt, S1, Precision::Confusion() );
1117 projector.LowerDistanceParameters( U, V );
c6541a0c 1118 if (Abs(U) <= Precision::Confusion() || Abs(U-2.*M_PI) <= Precision::Confusion())
7fd59977 1119 {
1120 aCurve->Reverse();
1121 Candidates.Append( aCurve );
1122 }
1123 }
1124 }
1125
1126 if(Candidates.Length() == 0)
1127 {
1128// errStat = Draft_EdgeRecomputation;
1129// badShape = TopoDS::Edge(ite.Key());
1130// return;
1131 for (i = 1; i <= i2s.NbLines(); i++)
1132 Candidates.Append( i2s.Line(i) );
1133 }
1134 }
1135 else
1136 {
1137 for (i = 1; i <= i2s.NbLines(); i++)
1138 Candidates.Append( i2s.Line(i) );
1139 }
1140
1141 Handle( Geom_Curve ) FirstCurve;
1142 if (Candidates.Length() > 1)
1143 {
1144 Dist2Min = RealLast();
1145 for (i = 1; i <= Candidates.Length(); i++)
1146 {
1147 Handle( Geom_Curve ) aCurve = Candidates(i);
1148 gp_Pnt Pnt = aCurve->Value( aCurve->FirstParameter() );
1149 Dist2 = Pnt.SquareDistance( pfv );
1150 if (Dist2 < Dist2Min)
1151 {
1152 Dist2Min = Dist2;
1153 FirstCurve = aCurve;
1154 }
1155 }
1156 }
1157 else
1158 FirstCurve = Candidates(1);
1159
1160 //Glueing
1161 TColGeom_SequenceOfCurve Curves;
1162 for (i = 1; i <= i2s.NbLines(); i++)
1163 if (FirstCurve != i2s.Line(i))
1164 Curves.Append( i2s.Line(i) );
1165
1166 TColGeom_SequenceOfCurve ToGlue;
1167 gp_Pnt EndPoint = FirstCurve->Value( FirstCurve->LastParameter() );
1168 Standard_Boolean added = Standard_True;
1169 while (added)
1170 {
1171 added = Standard_False;
1172 for (i = 1; i <= Curves.Length(); i++)
1173 {
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())
1179 {
1180 ToGlue.Append( aCurve );
1181 EndPoint = plast;
1182 Curves.Remove(i);
1183 added = Standard_True;
1184 break;
1185 }
1186 if (plast.Distance( EndPoint ) <= Precision::Confusion())
1187 {
1188 aCurve->Reverse();
1189 ToGlue.Append( aCurve );
1190 EndPoint = pfirst;
1191 Curves.Remove(i);
1192 added = Standard_True;
1193 break;
1194 }
1195 }
1196 }
1197
1198 if (FirstCurve.IsNull()) {
1199 errStat = Draft_EdgeRecomputation;
1200 badShape = TopoDS::Edge(ite.Key());
1201 return;
1202 }
1203
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 );
1207
1208 newC = Concat.BSplineCurve();
1209
1210 TheCurve.Load( newC );
1211 Extrema_ExtPC myExtPC( pfv, TheCurve );
1212 Dist2Min = RealLast();
1213 for (i = 1; i <= myExtPC.NbExt(); i++)
1214 {
1215 Dist2 = myExtPC.SquareDistance(i);
1216 if (Dist2 < Dist2Min)
1217 {
1218 Dist2Min = Dist2;
1219 pmin = myExtPC.Point(i).Parameter();
1220 }
1221 }
1222
1223 newC->D1(pmin,pfv,newd1);
1224 Standard_Boolean YaRev = d1fv.Dot(newd1) < 0.;
1225
1226 if (YaRev)
1227 newC->Reverse();
1228 /*
1229 if (i2s.HasLineOnS1(imin)) {
1230 Einf.ChangeFirstPC() = i2s.LineOnS1(imin);
1231 if ( YaRev)
1232 Einf.ChangeFirstPC()->Reverse();
1233 }
1234
1235 if (i2s.HasLineOnS2(imin)) {
1236 Einf.ChangeSecondPC() = i2s.LineOnS2(imin);
1237 if ( YaRev)
1238 Einf.ChangeSecondPC()->Reverse();
1239 }
1240 */
1241 } // else: i2s.NbLines() > 2 && S1 is Cylinder or Cone
1242
1243 Einf.Tolerance(Max(Einf.Tolerance(), i2s.TolReached3d()));
0d969553 1244 } // End step KPart
7fd59977 1245 }
0d969553 1246 else { // case of tangency
7fd59977 1247 const TopoDS_Face& F1 = Einf.FirstFace();
1248 const TopoDS_Face& F2 = Einf.SecondFace();
1249
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());
1255 return;
1256 }
1257 if (aLocalS1->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1258 aLocalS1 = Handle(Geom_RectangularTrimmedSurface)::
1259 DownCast(aLocalS1)->BasisSurface();
1260 }
1261 if (aLocalS2->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1262 aLocalS2 = Handle(Geom_RectangularTrimmedSurface)::
1263 DownCast(aLocalS2)->BasisSurface();
1264 }
1265
1266 gp_Dir dirextr;
1267 //Standard_Boolean dirfound = Standard_False;
1268 if (aLocalS1->DynamicType() == STANDARD_TYPE(Geom_CylindricalSurface)) {
1269 gp_Cylinder cyl =
1270 Handle(Geom_CylindricalSurface)::DownCast(aLocalS1)->Cylinder();
1271 dirextr = cyl.Axis().Direction();
1272 //dirfound = Standard_True;
0d969553 1273 // see direction...
7fd59977 1274
1275 }
1276 else if (aLocalS1->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
1277 dirextr = Handle(Geom_SurfaceOfLinearExtrusion)::
1278 DownCast(aLocalS1)->Direction();
1279 //dirfound = Standard_True;
0d969553 1280 // see direction...
7fd59977 1281
0d969553 1282 // Here it is possible to calculate PCurve.
7fd59977 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;
1292 }
1293 }
1294
1295 else if (aLocalS2->DynamicType() == STANDARD_TYPE(Geom_CylindricalSurface)) {
1296 gp_Cylinder cyl =
1297 Handle(Geom_CylindricalSurface)::DownCast(aLocalS2)->Cylinder();
1298 dirextr = cyl.Axis().Direction();
0d969553
Y
1299 // dirfound = Standard_True;
1300 // see direction...
7fd59977 1301
1302 }
1303 else if (aLocalS2->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
1304 dirextr = Handle(Geom_SurfaceOfLinearExtrusion)::
1305 DownCast(aLocalS2)->Direction();
0d969553
Y
1306 // dirfound = Standard_True;
1307 // see direction...
7fd59977 1308
0d969553 1309 // Here it is possible to calculate PCurve.
7fd59977 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;
1319 }
1320 }
1321 newC = new Geom_Line(ptfixe,dirextr);
1322
1323 gp_Pnt pfv;
1324 gp_Vec d1fv,newd1;
1325 C->D1(0.,pfv,d1fv);
1326 newC->D1(0.,pfv,newd1);
1327 Standard_Boolean YaRev = d1fv.Dot(newd1) <0.;
1328 if (YaRev) {
1329 newC->Reverse();
1330 if(!Einf.FirstPC().IsNull()) {
1331 Einf.ChangeFirstPC()->Reverse();
1332 }
1333 if(!Einf.SecondPC().IsNull()) {
1334 Einf.ChangeSecondPC()->Reverse();
1335 }
1336 }
1337 }
1338
1339 Handle(Geom_TrimmedCurve) T = Handle(Geom_TrimmedCurve)::DownCast(newC);
1340 if (!T.IsNull()) newC = T->BasisCurve();
1341 Einf.ChangeGeometry() = newC;
1342 }
1343 else if (!Einf.NewGeometry()){
0d969553 1344 // set existing curve 3D
7fd59977 1345 Handle(Geom_TrimmedCurve) T = Handle(Geom_TrimmedCurve)::DownCast(C);
1346 if (!T.IsNull()) C = T->BasisCurve();
1347 Einf.ChangeGeometry() = C;
1348 }
1349 ite.Next();
1350 }
1351
0d969553 1352 // Calculate new vertices.
7fd59977 1353
1354 Draft_DataMapIteratorOfDataMapOfVertexVertexInfo itv(myVMap);
1355
1356 Handle(GeomAdaptor_HCurve) HAC = new GeomAdaptor_HCurve;
1357 Handle(GeomAdaptor_HSurface) HAS = new GeomAdaptor_HSurface;
1358
1359 while (itv.More()) {
1360 GeomAdaptor_Curve AC;
1361 GeomAdaptor_Surface AS;
1362
1363 Draft_VertexInfo& Vinf = myVMap(itv.Key());
1364 if (!Choose(myFMap,myEMap,itv.Key(),Vinf,AC,AS)) {
1365
0d969553 1366// no concerted edge => alignment of two consecutive edges.
7fd59977 1367 gp_Pnt pvt;
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();
1378
1379#ifdef DEB
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;
1385 }
1386#endif
1387
1388 Standard_Real dion=pvt.SquareDistance(vtori);
1389 Vinf.NextEdge();
1390 if (Vinf.MoreEdge()) {
1391 const TopoDS_Edge& Edg2 = Vinf.Edge();
1392 //const Draft_EdgeInfo& Einf2 = myEMap(Edg2);
1393 Draft_EdgeInfo& Einf2 = myEMap(Edg2);
1394// Standard_Real f;
1395 gp_Pnt opvt;
1396 Einf2.Geometry()->D0(Vinf.Parameter(Edg2), opvt);
1397
1398#ifdef DEB
1399 if (VertexRecomp!=0) {
1400 cout << " Edg 2 :" << Vinf.Parameter(Vinf.Edge()) << endl;
1401 cout << "opvt " << opvt.X() << " " << opvt.Y() << " " << opvt.Z() << endl;
1402 }
1403#endif
1404
1405 if (opvt.SquareDistance(vtori) < dion) {
1406 pvt = opvt;
1407 }
1408 //Vinf.ChangeParameter(Edg2) = Parameter(Einf2.Geometry(), pvt);
1409 Standard_Integer done;
1410 Standard_Real param = Parameter(Einf2.Geometry(), pvt, done);
1411 if (done != 0)
1412 {
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 );
1416 }
1417 else
1418 Vinf.ChangeParameter(Edg2) = param;
1419 }
1420
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);
1425 if (done != 0)
1426 {
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 );
1430 }
1431 else
1432 Vinf.ChangeParameter(Edg1) = param;
1433 itv.Next();
1434 continue;
1435 }
1436
1437
1438 errStat = Draft_VertexRecomputation;
1439 badShape = TopoDS::Vertex(itv.Key());
1440 return;
1441 }
1442
1443 IntCurveSurface_HInter myintcs;
1444 HAC->Set(AC);
1445 HAS->Set(AS);
1446 myintcs.Perform(HAC,HAS);
1447
1448 if (!myintcs.IsDone()) {
1449 errStat = Draft_VertexRecomputation;
1450 badShape = TopoDS::Vertex(itv.Key());
1451 return;
1452 }
1453
1454 gp_Pnt vtori = BRep_Tool::Pnt(itv.Key());
1455 gp_Pnt pvt;
1456
1457 Standard_Integer nbsol = myintcs.NbPoints();
1458 if (nbsol <= 0)
1459 {
1460 Extrema_ExtCS extr( AC, AS, Precision::PConfusion(), Precision::PConfusion() );
1461
1462 if(!extr.IsDone() || extr.NbExt() == 0) {
1463 errStat = Draft_VertexRecomputation;
1464 badShape = TopoDS::Vertex(itv.Key());
1465 return;
1466 }
1467
1468
1469 Standard_Real disref = RealLast();
1470 Standard_Integer iref = 0;
1471 Extrema_POnCurv Pc;
1472 Extrema_POnSurf Ps;
1473 for (Standard_Integer i = 1; i <= extr.NbExt(); i++)
1474 {
1475 extr.Points( i, Pc, Ps );
1476 Standard_Real distemp = Pc.Value().SquareDistance(vtori);
1477 if ( distemp < disref)
1478 {
1479 disref = distemp;
1480 iref = i;
1481 }
1482 }
1483 extr.Points( iref, Pc, Ps );
1484 pvt = Pc.Value();
1485 }
1486 else
1487 {
1488 Standard_Real disref = RealLast();
1489 Standard_Integer iref = 0;
1490 for (Standard_Integer i = 1; i <= nbsol; i++)
1491 {
1492 Standard_Real distemp = myintcs.Point(i).Pnt().SquareDistance(vtori);
1493 if ( distemp < disref)
1494 {
1495 disref = distemp;
1496 iref = i;
1497 }
1498 }
1499 pvt = myintcs.Point(iref).Pnt();
1500 }
1501
1502 Vinf.ChangeGeometry() = pvt;
1503
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);
1511 if (done != 0)
1512 {
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 );
1516 }
1517 else
1518 Vinf.ChangeParameter(Edg) = param;
1519 }
1520 itv.Next();
1521 }
1522 }
1523
0d969553 1524 // small loop of validation/protection
7fd59977 1525
1526 for (Draft_DataMapIteratorOfDataMapOfEdgeEdgeInfo ite(myEMap);
1527 ite.More(); ite.Next()) {
1528 const TopoDS_Edge& edg = TopoDS::Edge(ite.Key());
1529
1530 TopoDS_Vertex Vf,Vl;
1531 TopExp::Vertices(edg,Vf,Vl);
1532 if (edg.Orientation() == TopAbs_REVERSED) {
1533 Vf.Reverse();
1534 Vl.Reverse();
1535 }
1536 Standard_Real pf,pl,tolerance;
1537 if (!NewParameter(Vf,edg,pf,tolerance)) {
1538 pf = BRep_Tool::Parameter(Vf,edg);
1539 }
1540 if (!NewParameter(Vl,edg,pl,tolerance)) {
1541 pl = BRep_Tool::Parameter(Vl,edg);
1542 }
1543 if (pl <= pf) {
1544// const Handle(Geom_Curve) gc=ite.Value().Geometry();
1545// if (!gc.IsNull()) {
1546// pl = gc->LastParameter();
1547// pf = gc->FirstParameter();
1548// }
1549 Handle( Geom_Curve ) theCurve = myEMap(edg).Geometry();
1550 if (theCurve->IsClosed())
1551 {
1552 // pf >= pl
1553 Standard_Real FirstPar = theCurve->FirstParameter(), LastPar = theCurve->LastParameter();
1554 Standard_Real pconf = Precision::PConfusion();
1555 if (Abs( pf - LastPar ) <= pconf)
1556 pf = FirstPar;
1557 else if (Abs( pl - FirstPar ) <= pconf)
1558 pl = LastPar;
1559
1560 if(pl <= pf) {
1561 pl += (LastPar-FirstPar);
1562 }
1563
1564 }
1565 if (pl <= pf) {
1566 errStat = Draft_EdgeRecomputation;
1567 badShape = TopoDS::Edge(ite.Key());
1568 return;
1569 }
1570 }
1571 if (myVMap.IsBound( Vf ))
1572 myVMap(Vf).ChangeParameter(edg) = pf;
1573 if (myVMap.IsBound( Vl ))
1574 myVMap(Vl).ChangeParameter(edg) = pl;
1575 }
1576}
1577
1578
1579
1580//=======================================================================
1581//function : NewSurface
1582//purpose :
1583//=======================================================================
1584
1585Handle(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)
1591{
1592 Handle(Geom_Surface) NewS;
1593
1594 Handle(Standard_Type) TypeS = S->DynamicType();
1595
1596 if (TypeS == STANDARD_TYPE(Geom_Plane)) {
1597 gp_Pln Pl = Handle(Geom_Plane)::DownCast(S)->Pln();
1598 gp_Ax1 Axe;
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));
1603 }
1604 else {
1605 NewS = S;
1606 }
1607 }
1608 }
1609 else if (TypeS == STANDARD_TYPE(Geom_CylindricalSurface)) {
1610 Standard_Real testdir = Direction.Dot(NeutralPlane.Axis().Direction());
1611 if (Abs(testdir) <= 1.-Precision::Angular()) {
1612#ifdef DEB
1613 cout << "NewSurfaceCyl:Draft_Direction_and_Neutral_Perpendicular" << endl;
1614#endif
1615 return NewS;
1616 }
1617 gp_Cylinder Cy = Handle(Geom_CylindricalSurface)::DownCast(S)->Cylinder();
1618 testdir = Direction.Dot(Cy.Axis().Direction());
1619 if (Abs(testdir) <= 1.-Precision::Angular()) {
1620#ifdef DEB
1621 cout << "NewSurfaceCyl:Draft_Direction_and_Cylinder_Perpendicular" << endl;
1622#endif
1623 return NewS;
1624 }
788cbaf4 1625 if (Abs(Angle) > Precision::Angular())
1626 {
7fd59977 1627 IntAna_QuadQuadGeo i2s;
1628 i2s.Perform(NeutralPlane,Cy,Precision::Angular(),Precision::Confusion());
788cbaf4 1629 Standard_Boolean isIntDone = i2s.IsDone();
1630
1631 if(i2s.TypeInter() == IntAna_Ellipse)
1632 {
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);
1637 }
1638
1639 if (!isIntDone || i2s.TypeInter() != IntAna_Circle) {
7fd59977 1640#ifdef DEB
1641 cout << "NewSurfaceCyl:Draft_Intersection_Neutral_Cylinder_NotDone" << endl;
1642#endif
1643 return NewS;
1644 }
1645 gp_Ax3 axcone = Cy.Position();
0d969553 1646 // Pb : Where is the material???
7fd59977 1647 Standard_Real alpha = Angle;
1648 Standard_Boolean direct(axcone.Direct());
1649 if ((direct && Oris == TopAbs_REVERSED) ||
1650 (!direct && Oris == TopAbs_FORWARD)) {
1651 alpha = -alpha;
1652 }
1653
1654 gp_Pnt Center = i2s.Circle(1).Location();
1655 if (testdir <0.) {
1656 alpha = -alpha;
1657 }
1658 Standard_Real Z = ElCLib::LineParameter(Cy.Axis(),Center);
1659 Standard_Real Rad = Cy.Radius()+Z*Tan(alpha);
1660 if (Rad < 0.) {
1661 Rad = -Rad;
1662 }
1663 else {
1664 alpha = -alpha;
1665 }
1666 gp_Cone co(axcone,alpha,Rad);
1667 NewS = new Geom_ConicalSurface(co);
1668 }
1669 else {
1670 NewS = S;
1671 }
1672 }
1673 else if (TypeS == STANDARD_TYPE(Geom_ConicalSurface)) {
1674
1675 Standard_Real testdir = Direction.Dot(NeutralPlane.Axis().Direction());
1676 if (Abs(testdir) <= 1.-Precision::Angular()) {
1677#ifdef DEB
1678 cout << "NewSurfaceCone:Draft_Direction_and_Neutral_Perpendicular" << endl;
1679#endif
1680 return NewS;
1681 }
1682
1683 gp_Cone Co1 = Handle(Geom_ConicalSurface)::DownCast(S)->Cone();
1684
1685 testdir = Direction.Dot(Co1.Axis().Direction());
1686 if (Abs(testdir) <= 1.-Precision::Angular()) {
1687#ifdef DEB
1688 cout << "NewSurfaceCone:Draft_Direction_and_Cone_Perpendicular" << endl;
1689#endif
1690 return NewS;
1691 }
1692
1693
1694 IntAna_QuadQuadGeo i2s;
1695 i2s.Perform(NeutralPlane,Co1,Precision::Angular(),Precision::Confusion());
1696 if (!i2s.IsDone() || i2s.TypeInter() != IntAna_Circle) {
1697#ifdef DEB
1698 cout << "NewSurfaceCone:Draft_Intersection_Neutral_Conical_NotDone" << endl;
1699#endif
1700 return NewS;
1701 }
1702 gp_Ax3 axcone = Co1.Position();
0d969553 1703 // Pb : Where is the material???
7fd59977 1704 Standard_Real alpha = Angle;
1705 Standard_Boolean direct(axcone.Direct());
1706 if ((direct && Oris == TopAbs_REVERSED) ||
1707 (!direct && Oris == TopAbs_FORWARD)) {
1708 alpha = -alpha;
1709 }
1710
1711 gp_Pnt Center = i2s.Circle(1).Location();
1712 if (Abs(Angle) > Precision::Angular()) {
1713 if (testdir <0.) {
1714 alpha = -alpha;
1715 }
1716 Standard_Real Z = ElCLib::LineParameter(Co1.Axis(),Center);
1717 Standard_Real Rad = i2s.Circle(1).Radius()+Z*Tan(alpha);
1718 if (Rad < 0.) {
1719 Rad = -Rad;
1720 }
1721 else {
1722 alpha = -alpha;
1723 }
1724 if (Abs(alpha-Co1.SemiAngle()) < Precision::Angular()) {
1725 NewS = S;
1726 }
1727 else {
1728 gp_Cone co(axcone,alpha,Rad);
1729 NewS = new Geom_ConicalSurface(co);
1730 }
1731 }
1732 else {
1733 NewS = new
1734 Geom_CylindricalSurface(gp_Cylinder(axcone,i2s.Circle(1).Radius()));
1735 }
1736 }
1737 else {
1738#ifdef DEB
1739 cout << "NewSurface:Draft_SurfNotYetImplemented" << endl;
1740#endif
1741 }
1742 return NewS;
1743}
1744
1745
1746//=======================================================================
1747//function : NewCurve
1748//purpose :
1749//=======================================================================
1750
1751Handle(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 )
1759
1760{
1761 Handle(Geom_Curve) NewC;
1762
1763 Handle(Standard_Type) TypeS = S->DynamicType();
1764
1765 if (TypeS == STANDARD_TYPE(Geom_Plane)) {
1766 gp_Pln Pl = Handle(Geom_Plane)::DownCast(S)->Pln();
1767 gp_Ax1 Axe;
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));
1772 }
1773 else {
1774 NewC = C;
1775 }
1776 }
1777 return NewC;
1778 }
1779
1780
1781 if (C->DynamicType() != STANDARD_TYPE(Geom_Line)) {
1782 return NewC;
1783 }
1784
1785
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()) {
1789// return NewC;
1790// }
1791 gp_Dir Norm;
1792 if (TypeS == STANDARD_TYPE(Geom_CylindricalSurface)) {
1793 Standard_Real U,V;
1794 gp_Vec d1u,d1v;
1795 gp_Pnt pbid;
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);
1800 }
1801 else if (TypeS == STANDARD_TYPE(Geom_ConicalSurface)) {
1802 Standard_Real U,V;
1803 gp_Vec d1u,d1v;
1804 gp_Pnt pbid;
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);
1809 }
1810
1811 IntAna_IntConicQuad ilipl(lin,NeutralPlane,Precision::Angular());
1812 if (ilipl.IsDone() && ilipl.NbPoints() != 0){
1813 if (Oris == TopAbs_REVERSED) {
1814 Norm.Reverse();
1815 }
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.) {
1820 lires.Reverse();
1821 }
1822 NewC = new Geom_Line(lires);
1823 }
1824 return NewC;
1825}
1826
1827
1828//=======================================================================
1829//function : Choose
1830//purpose :
1831//=======================================================================
1832
1833static 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)
1839{
1840 gp_Vec tgref;
1841 Vinf.InitEdgeIterator();
1842
0d969553 1843 // Find a regular edge with null SecondFace
7fd59977 1844 while (Vinf.MoreEdge()) {
1845 const TopoDS_Edge& E1 = Vinf.Edge();
1846 const Draft_EdgeInfo& Einf1 = theEMap(E1);
1847 if (Einf1.SecondFace().IsNull()) {
1848 break;
1849 }
1850 else {
1851 GeomAbs_Shape te = BRep_Tool::Continuity(E1,Einf1.FirstFace(),
1852 Einf1.SecondFace());
1853 if (te >= GeomAbs_G1) {
1854 break;
1855 }
1856 }
1857 Vinf.NextEdge();
1858 }
0d969553 1859 if (!Vinf.MoreEdge()) { // take the first edge
7fd59977 1860 Vinf.InitEdgeIterator();
1861 }
1862
1863 const TopoDS_Edge& Eref = Vinf.Edge();
1864 //const Draft_EdgeInfo& Einf = theEMap(Eref);
1865 Draft_EdgeInfo& Einf = theEMap(Eref);
1866
1867 AC.Load(Einf.Geometry());
1868
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()));
1873 gp_Pnt ptbid;
1874 //prm = Parameter(C,BRep_Tool::Pnt(Vtx));
1875 Standard_Integer done;
1876 Standard_Real param = Parameter( C, BRep_Tool::Pnt(Vtx), done );
1877 if (done != 0)
1878 {
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 );
1882 }
1883 else
1884 prm = param;
1885 C->D1(prm,ptbid,tgref);
1886
1887
1888 Vinf.InitEdgeIterator();
1889 while (Vinf.MoreEdge()) {
0d969553 1890 // Find a non tangent edge
7fd59977 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())
1897 <= GeomAbs_C0) {
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 );
1903 if (anewdone != 0)
1904 {
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 );
1908 }
1909 else
1910 prm = anewparam;
1911 gp_Vec tg;
1912 C->D1(prm,ptbid,tg);
1913 if (tg.CrossMagnitude(tgref) > Precision::Confusion()) {
1914 break;
1915 }
1916 }
1917 }
1918 Vinf.NextEdge();
1919 }
1920 if (!Vinf.MoreEdge()) {
1921 return Standard_False;
1922 }
1923
1924 const Draft_EdgeInfo& Einf2 = theEMap(Vinf.Edge());
1925 if (!Einf.SecondFace().IsNull()) {
1926
1927 if (Einf2.FirstFace().IsSame(Einf.FirstFace()) ||
1928 Einf2.FirstFace().IsSame(Einf.SecondFace())) {
1929 AS.Load(theFMap(Einf2.SecondFace()).Geometry());
1930 }
1931 else {
1932 AS.Load(theFMap(Einf2.FirstFace()).Geometry());
1933 }
1934 }
1935 else {
1936 if (Einf2.FirstFace().IsSame(Einf.FirstFace())) {
1937 AS.Load(theFMap(Einf2.SecondFace()).Geometry());
1938 }
1939 else {
1940 AS.Load(theFMap(Einf2.FirstFace()).Geometry());
1941 }
1942 }
1943 return Standard_True;
1944}
1945
1946
1947//=======================================================================
1948//function : Parameter
1949//purpose :
1950//=======================================================================
1951
1952static Standard_Real Parameter(const Handle(Geom_Curve)& C,
1953 const gp_Pnt& P,
1954 Standard_Integer& done)
1955{
1956 done = 0;
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();
1962 }
1963 Standard_Real param;
1964 if (ctyp == STANDARD_TYPE(Geom_Line)) {
1965 param = ElCLib::Parameter(Handle(Geom_Line)::DownCast(cbase)->Lin(),P);
1966 }
1967 else if (ctyp == STANDARD_TYPE(Geom_Circle)) {
1968 param = ElCLib::Parameter(Handle(Geom_Circle)::DownCast(cbase)->Circ(),P);
c6541a0c 1969 if (Abs(2.*M_PI-param) <=Epsilon(2.*M_PI)) {
7fd59977 1970 param = 0.;
1971 }
1972 }
1973 else if (ctyp == STANDARD_TYPE(Geom_Ellipse)) {
1974 param = ElCLib::Parameter(Handle(Geom_Ellipse)::DownCast(cbase)->Elips(),P);
c6541a0c 1975 if (Abs(2.*M_PI-param) <=Epsilon(2.*M_PI)) {
7fd59977 1976 param = 0.;
1977 }
1978 }
1979 else if (ctyp == STANDARD_TYPE(Geom_Parabola)) {
1980 param = ElCLib::Parameter(Handle(Geom_Parabola)::DownCast(cbase)->Parab(),P);
1981 }
1982 else if (ctyp == STANDARD_TYPE(Geom_Hyperbola)) {
1983 param = ElCLib::Parameter(Handle(Geom_Hyperbola)::DownCast(cbase)->Hypr(),P);
1984 }
1985 else {
1986 GeomAdaptor_Curve TheCurve(C);
1987 Extrema_ExtPC myExtPC(P,TheCurve);
1988 if (!myExtPC.IsDone()) {
1989 Standard_Failure::Raise();
1990 }
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) {
1997 Dist2Min = Dist2;
1998 jmin = j;
1999 }
2000 }
2001 param = myExtPC.Point(jmin).Parameter();
2002 }
2003 else {
2004 Standard_Real dist1_2,dist2_2;
2005 gp_Pnt p1b,p2b;
2006 myExtPC.TrimmedSquareDistances(dist1_2,dist2_2,p1b,p2b);
2007 if (dist1_2 < dist2_2) {
2008 done = -1;
2009 param = TheCurve.FirstParameter();
2010 }
2011 else {
2012 done = 1;
2013 param = TheCurve.LastParameter();
2014 }
2015 }
2016
2017 if (cbase->IsPeriodic()) {
2018 Standard_Real Per = cbase->Period();
2019 Standard_Real Tolp = Precision::Parametric(Precision::Confusion());
2020 if (Abs(Per-param) <= Tolp) {
2021 param = 0.;
2022 }
2023 }
2024 }
2025 return param;
2026}
2027
2028//=======================================================================
2029//function : SmartParameter
2030//purpose :
2031//=======================================================================
2032
2033static Standard_Real SmartParameter(Draft_EdgeInfo& Einf,
2034 const Standard_Real EdgeTol,
2035 const gp_Pnt& Pnt,
2036 const Standard_Integer sign,
2037 const Handle(Geom_Surface)& S1,
2038 const Handle(Geom_Surface)& S2)
2039{
2040 Handle( Geom2d_Curve ) NewC2d;
2041 Standard_Real Tol = Precision::Confusion();
2042 Standard_Real Etol = EdgeTol;
2043
2044 Handle( Geom2d_Curve ) pcu1 = Einf.FirstPC();
2045 Handle( Geom2d_Curve ) pcu2 = Einf.SecondPC();
2046
2047 if (pcu1.IsNull())
2048 {
2049 Handle( Geom_Curve ) theCurve = Einf.Geometry();
2050 pcu1 = GeomProjLib::Curve2d( theCurve, theCurve->FirstParameter(), theCurve->LastParameter(), S1, Etol );
2051 Einf.ChangeFirstPC() = pcu1;
2052 }
2053 if (pcu2.IsNull())
2054 {
2055 Handle( Geom_Curve ) theCurve = Einf.Geometry();
2056 pcu2 = GeomProjLib::Curve2d( theCurve, theCurve->FirstParameter(), theCurve->LastParameter(), S2, Etol );
2057 Einf.ChangeSecondPC() = pcu2;
2058 }
2059
2060 GeomAPI_ProjectPointOnSurf Projector( Pnt, S1 );
2061 Standard_Real U, V;
2062 Projector.LowerDistanceParameters( U, V );
2063
2064 NewC2d = Einf.FirstPC();
2065 if (NewC2d->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve))
2066 NewC2d = (Handle(Geom2d_TrimmedCurve)::DownCast(NewC2d))->BasisCurve();
2067
2068 gp_Pnt2d P2d( U, V );
2069 Geom2dAPI_ProjectPointOnCurve Projector2d( P2d, NewC2d );
2070 if (Projector2d.NbPoints() == 0 || Projector2d.LowerDistance() > Tol)
2071 {
2072 Handle( Geom2d_BSplineCurve ) BCurve;
2073 if (NewC2d->DynamicType() != STANDARD_TYPE(Geom2d_BSplineCurve))
2074 BCurve = Geom2dConvert::CurveToBSplineCurve( NewC2d );
2075 else
2076 BCurve = Handle( Geom2d_BSplineCurve )::DownCast( NewC2d );
2077 if (sign == -1)
2078 {
2079 TColgp_Array1OfPnt2d PntArray( 1, 2 );
2080 PntArray(1) = P2d;
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();
2086 }
2087 else
2088 {
2089 TColgp_Array1OfPnt2d PntArray( 1, 2 );
2090 PntArray(1) = BCurve->Pole( BCurve->NbPoles() );
2091 PntArray(2) = P2d;
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();
2096 }
2097 NewC2d = BCurve;
2098 }
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 );
2117
2118 if (sign == -1)
2119 return Einf.Geometry()->FirstParameter();
2120 else
2121 return Einf.Geometry()->LastParameter();
2122
2123}
2124
2125//=======================================================================
2126//function : Orientation
2127//purpose :
2128//=======================================================================
2129
2130static TopAbs_Orientation Orientation(const TopoDS_Shape& S,
2131 const TopoDS_Face& F)
2132{
2133//
0d969553 2134// change porting NT
7fd59977 2135//
2136 TopExp_Explorer expl ;
2137 expl.Init(S,
2138 TopAbs_FACE) ;
2139 while (expl.More()) {
2140 if (TopoDS::Face(expl.Current()).IsSame(F)) {
2141 return expl.Current().Orientation();
2142 }
2143 expl.Next();
2144 }
2145 return TopAbs_FORWARD;
2146}
2147
2148
2149//=======================================================================
2150//function : FindRotation
2151//purpose :
2152//=======================================================================
2153
2154static 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,
2159 gp_Ax1& Axe,
2160 Standard_Real& theta)
2161{
2162 IntAna_QuadQuadGeo i2pl(Pl,NeutralPlane,
2163 Precision::Angular(),Precision::Confusion());
2164
2165 if (i2pl.IsDone() && i2pl.TypeInter() == IntAna_Line) {
2166 gp_Lin li = i2pl.Line(1);
0d969553 2167 // Try to turn around this line
7fd59977 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)) {
2177 b = -b;
2178 c = -c;
2179 }
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;
2188 }
2189 // modified by NIZHNY-EAP Tue Nov 16 15:51:38 1999 ___BEGIN___
c6541a0c
D
2190 while (Abs(theta)>M_PI) {
2191 theta = theta + M_PI*(theta<0 ? 1 : -1);
7fd59977 2192 }
2193 // modified by NIZHNY-EAP Tue Nov 16 15:53:32 1999 ___END___
2194 Axe = li.Position();
2195 return Standard_True;
2196 }
2197 }
2198 }
2199 return Standard_False;
2200}
2201