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