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