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