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