b311480e |
1 | // Created on: 1999-04-15 |
2 | // Created by: Roman LYGIN |
3 | // Copyright (c) 1999-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. |
b311480e |
16 | |
7fd59977 |
17 | // gka 23.06.99 S4208: using tool SU_TransferParameter |
18 | // pdn 13.07.99 synchronizing splitting values on 3d curve and pcurve |
19 | // abv 14.07.99 dealing with edges without 3d curve |
20 | // svv 10.01.00 porting on DEC |
21 | |
22 | #include <ShapeUpgrade_WireDivide.ixx> |
23 | #include <ShapeUpgrade.hxx> |
24 | #include <BRep_Tool.hxx> |
25 | #include <BRep_Builder.hxx> |
26 | #include <BRepLib_MakeFace.hxx> |
27 | #include <BRepLib_MakeWire.hxx> |
28 | #include <TopoDS.hxx> |
29 | #include <TopoDS_Vertex.hxx> |
30 | #include <TopoDS_Edge.hxx> |
31 | #include <TopoDS_Iterator.hxx> |
32 | #include <ShapeBuild_Edge.hxx> |
33 | #include <ShapeAnalysis_Edge.hxx> |
34 | #include <Precision.hxx> |
35 | #include <TopExp.hxx> |
36 | #include <TopExp_Explorer.hxx> |
37 | #include <TColStd_HSequenceOfReal.hxx> |
38 | #include <TColGeom_HArray1OfCurve.hxx> |
39 | #include <TColGeom2d_HArray1OfCurve.hxx> |
40 | #include <gp_Pnt.hxx> |
41 | #include <Geom_Curve.hxx> |
42 | #include <Geom2d_Curve.hxx> |
43 | #include <ShapeExtend.hxx> |
44 | #include <TColStd_Array1OfBoolean.hxx> |
45 | #include <ShapeBuild_ReShape.hxx> |
46 | #include <ShapeAnalysis_TransferParametersProj.hxx> |
47 | #include <ShapeUpgrade_FixSmallCurves.hxx> |
48 | #include <TopTools_SequenceOfShape.hxx> |
49 | #include <TColStd_SequenceOfReal.hxx> |
50 | #include <GeomAdaptor_HSurface.hxx> |
51 | #include <Geom2dAdaptor_HCurve.hxx> |
52 | #include <ShapeAnalysis_Curve.hxx> |
53 | #include <Adaptor3d_CurveOnSurface.hxx> |
54 | |
55 | //======================================================================= |
56 | //function : ShapeUpgrade_WireDivide |
57 | //purpose : |
58 | //======================================================================= |
59 | |
60 | ShapeUpgrade_WireDivide::ShapeUpgrade_WireDivide(): |
61 | ShapeUpgrade_Tool(), myStatus(0) |
62 | { |
63 | // if (ShapeUpgrade::Debug()) cout <<"ShapeUpgrade_WireDivide"<<endl; |
64 | mySplitCurve3dTool = new ShapeUpgrade_SplitCurve3d; |
65 | mySplitCurve2dTool = new ShapeUpgrade_SplitCurve2d; |
66 | myTransferParamTool = new ShapeAnalysis_TransferParametersProj; |
67 | myEdgeMode = 2; |
68 | myFixSmallCurveTool = new ShapeUpgrade_FixSmallCurves; |
69 | myEdgeDivide = new ShapeUpgrade_EdgeDivide; |
70 | } |
71 | |
72 | //======================================================================= |
73 | //function : Init |
74 | //purpose : |
75 | //======================================================================= |
76 | |
77 | void ShapeUpgrade_WireDivide::Init(const TopoDS_Wire& W, |
78 | const TopoDS_Face& F) |
79 | { |
80 | // if (ShapeUpgrade::Debug()) cout <<"ShapeUpgrade_WireDivide::Init with Wire, Face"<<endl; |
81 | myWire = W; |
82 | myFace = F; |
83 | myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK ); |
84 | } |
85 | |
86 | //======================================================================= |
87 | //function : Init |
88 | //purpose : |
89 | //======================================================================= |
90 | |
91 | void ShapeUpgrade_WireDivide::Init(const TopoDS_Wire& W, |
92 | const Handle(Geom_Surface)& S) |
93 | { |
94 | // if (ShapeUpgrade::Debug()) cout <<"ShapeUpgrade_WireDivide::Init with Wire, Surface "<<endl; |
95 | myWire = W; |
1c72dff6 |
96 | BRepLib_MakeFace mkf(S, Precision::Confusion()); |
7fd59977 |
97 | myFace = mkf.Face(); |
98 | myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK ); |
99 | } |
100 | |
101 | //======================================================================= |
102 | //function : Load |
103 | //purpose : |
104 | //======================================================================= |
105 | |
106 | void ShapeUpgrade_WireDivide::Load(const TopoDS_Wire& W) |
107 | { |
108 | myWire = W; |
109 | } |
110 | |
111 | //======================================================================= |
112 | //function : Load |
113 | //purpose : |
114 | //======================================================================= |
115 | |
116 | void ShapeUpgrade_WireDivide::Load(const TopoDS_Edge& E) |
117 | { |
118 | BRepLib_MakeWire MakeWire (E); |
119 | if (MakeWire.IsDone()) |
120 | Load (MakeWire.Wire()); |
121 | } |
122 | |
123 | //======================================================================= |
124 | //function : SetFace |
125 | //purpose : |
126 | //======================================================================= |
127 | |
128 | void ShapeUpgrade_WireDivide::SetFace(const TopoDS_Face& F) |
129 | { |
130 | myFace = F; |
131 | } |
132 | |
133 | //======================================================================= |
134 | //function : SetSurface |
135 | //purpose : |
136 | //======================================================================= |
137 | |
138 | void ShapeUpgrade_WireDivide::SetSurface(const Handle(Geom_Surface)& S) |
139 | { |
1c72dff6 |
140 | BRepLib_MakeFace mkf(S, Precision::Confusion()); |
7fd59977 |
141 | myFace = mkf.Face(); |
142 | } |
143 | |
144 | //======================================================================= |
145 | //function : SetSurface |
146 | //purpose : |
147 | //======================================================================= |
148 | |
149 | void ShapeUpgrade_WireDivide::SetSurface(const Handle(Geom_Surface)& S, |
150 | const TopLoc_Location& L) |
151 | { |
152 | BRep_Builder B; |
153 | B.MakeFace(myFace,S,L,Precision::Confusion()); |
154 | } |
155 | |
156 | //======================================================================= |
157 | //function : Perform |
158 | //purpose : |
159 | //======================================================================= |
160 | |
161 | static void CorrectSplitValues(const Handle(TColStd_HSequenceOfReal) orig3d, |
162 | const Handle(TColStd_HSequenceOfReal) orig2d, |
163 | Handle(TColStd_HSequenceOfReal) new2d, |
164 | Handle(TColStd_HSequenceOfReal) new3d) |
165 | { |
166 | Standard_Real preci = Precision::PConfusion(); |
167 | Standard_Integer len3d = orig3d->Length(); |
168 | Standard_Integer len2d = orig2d->Length(); |
169 | TColStd_Array1OfBoolean fixNew2d (1, len3d); |
170 | fixNew2d.Init (Standard_False); |
171 | TColStd_Array1OfBoolean fixNew3d (1, len2d); |
172 | fixNew3d.Init (Standard_False); |
173 | Standard_Real Last3d = orig3d->Value(len3d); |
174 | Standard_Real Last2d = orig2d->Value(len2d); |
175 | |
176 | Standard_Integer i;// svv #1 |
177 | for( i = 1; i <= len3d ; i++) { |
178 | Standard_Real par = new2d->Value(i); |
179 | Standard_Integer index = 0; |
180 | for(Standard_Integer j = 1; j <= len2d && !index; j++) |
181 | if(Abs(par-orig2d->Value(j)) < preci) |
182 | index = j; |
183 | if(index&&!fixNew3d(index)) { |
184 | Standard_Real newPar = orig2d->Value(index); |
185 | new2d->SetValue(i,newPar); |
186 | fixNew2d(i) = Standard_True; |
187 | Standard_Real newPar3d = orig3d->Value(i); |
188 | new3d->SetValue(index,newPar3d); |
189 | fixNew3d(index) = Standard_True; |
190 | } |
191 | } |
192 | |
193 | for(i = 1; i <= len2d ; i++) { |
194 | Standard_Real par = new3d->Value(i); |
195 | Standard_Integer index = 0; |
196 | for(Standard_Integer j = 1; j <= len3d && !index; j++) |
197 | if(Abs(par-orig3d->Value(j)) < preci) |
198 | index = j; |
199 | if(index&&!fixNew2d(index)) { |
200 | Standard_Real newPar = orig3d->Value(index); |
201 | new3d->SetValue(i,newPar); |
202 | fixNew3d(i) = Standard_True; |
203 | Standard_Real newPar2d = orig2d->Value(i); |
204 | new2d->SetValue(index,newPar2d); |
205 | fixNew2d(index) = Standard_True; |
206 | } |
207 | } |
208 | |
209 | Standard_Real dpreci = 2* preci; |
210 | for(i = 1; i < len3d; i++) { |
211 | Standard_Real dist = new2d->Value(i+1) - new2d->Value(i); |
212 | if(dist < preci) { |
213 | if(fixNew2d(i+1)) { |
214 | //changing |
215 | Standard_Real tmp = new2d->Value(i+1); |
216 | new2d->SetValue(i+1,new2d->Value(i)+dpreci); |
217 | new2d->SetValue(i,tmp); |
218 | fixNew2d(i) = Standard_True; |
219 | fixNew2d(i+1) = Standard_False; |
220 | } |
221 | else |
222 | new2d->SetValue(i+1,new2d->Value(i)+dpreci); |
223 | } |
224 | } |
225 | if(new2d->Value(len3d) > Last3d) { |
226 | Standard_Integer ind; // svv #1 |
227 | for( ind = len3d; ind > 1 && !fixNew2d(ind); ind--); |
228 | Standard_Real lastFix = new2d->Value(ind); |
229 | for(i = len3d; i >= ind; i--) { |
230 | new2d->SetValue(i,lastFix); |
231 | lastFix-=dpreci; |
232 | } |
233 | } |
234 | |
235 | for(i = 1; i < len2d; i++) { |
236 | Standard_Real dist = new3d->Value(i+1) - new3d->Value(i); |
237 | if(dist < preci) { |
238 | if(fixNew3d(i+1)) { |
239 | //changing |
240 | Standard_Real tmp = new3d->Value(i+1); |
241 | new3d->SetValue(i+1,new3d->Value(i)+dpreci); |
242 | new3d->SetValue(i,tmp); |
243 | fixNew3d(i) = Standard_True; |
244 | fixNew3d(i+1) = Standard_False; |
245 | } |
246 | else |
247 | new3d->SetValue(i+1,new3d->Value(i)+dpreci); |
248 | } |
249 | } |
250 | if(new3d->Value(len2d) > Last2d) { |
251 | Standard_Integer ind; // svv #1 |
252 | for(ind = len2d; ind > 1 && !fixNew3d(ind); ind--); |
253 | Standard_Real lastFix = new3d->Value(ind); |
254 | for(i = len2d; i >= ind; i--) { |
255 | new3d->SetValue(i,lastFix); |
256 | lastFix-=dpreci; |
257 | } |
258 | } |
259 | } |
260 | |
261 | void ShapeUpgrade_WireDivide::Perform () |
262 | { |
263 | |
264 | myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK ); |
265 | |
266 | // if (ShapeUpgrade::Debug()) cout << "ShapeUpgrade_WireDivide::Perform" << endl; |
267 | |
268 | BRep_Builder B; |
269 | ShapeAnalysis_Edge sae; |
270 | |
271 | TopoDS_Wire newWire; |
272 | B.MakeWire (newWire); |
273 | TopLoc_Location Loc; |
274 | Handle(Geom_Surface) Surf; |
275 | if(!myFace.IsNull()) |
276 | Surf = BRep_Tool::Surface(myFace, Loc); |
277 | |
278 | Standard_Boolean isSplit3d = Standard_True; |
279 | switch(myEdgeMode) { |
280 | case 0: if(!myFace.IsNull()) isSplit3d = Standard_False; break; |
281 | case 1: if(myFace.IsNull()) isSplit3d = Standard_False; break; |
282 | default : break; |
283 | } |
284 | myEdgeDivide->SetFace(myFace); |
285 | if(isSplit3d) |
286 | myEdgeDivide->SetSplitCurve3dTool(GetSplitCurve3dTool()); |
287 | myEdgeDivide->SetSplitCurve2dTool(GetSplitCurve2dTool()); |
288 | for (TopoDS_Iterator ItW (myWire,Standard_False); ItW.More(); ItW.Next()) { |
289 | // for each Edge: |
290 | TopoDS_Shape sh = Context()->Apply(ItW.Value(),TopAbs_SHAPE); |
291 | for(TopExp_Explorer exp(sh,TopAbs_EDGE); exp.More(); exp.Next()) { |
292 | TopoDS_Edge E = TopoDS::Edge(exp.Current()); |
293 | // if (ShapeUpgrade::Debug()) cout << ".. Edge " << (void*) &(*E.TShape()) << endl; |
294 | |
295 | // skip degenerated edges (and also INTERNAL/EXTERNAL, to avoid failures) |
296 | if ( E.Orientation() == TopAbs_INTERNAL || E.Orientation() == TopAbs_EXTERNAL ) { |
297 | B.Add ( newWire, E ); |
298 | continue; |
299 | } |
300 | |
301 | if(!myEdgeDivide->Compute(E)) { |
302 | B.Add ( newWire, E ); |
303 | continue; |
304 | } |
305 | // first iteration: getting split knots |
306 | // on 3D curve: preliminary |
307 | |
308 | Handle(ShapeAnalysis_TransferParameters) theTransferParamTool = GetTransferParamTool(); |
309 | theTransferParamTool->SetMaxTolerance(MaxTolerance()); |
310 | theTransferParamTool->Init(E,myFace); |
311 | Standard_Boolean wasSR = theTransferParamTool->IsSameRange(); |
312 | |
313 | // on pcurve(s): all knots |
314 | // assume that if seam-edge, its pcurve1 and pcurve2 has the same split knots !!! |
315 | Handle(TColStd_HSequenceOfReal) theKnots3d = myEdgeDivide->Knots3d(); |
316 | Handle(TColStd_HSequenceOfReal) theKnots2d = myEdgeDivide->Knots2d(); |
317 | |
318 | // second iteration: transfer parameters and build segments |
319 | Handle(TColStd_HSequenceOfReal) SplitValues2d; |
320 | Handle(TColStd_HSequenceOfReal) SplitValues3d; |
321 | if(myEdgeDivide->HasCurve2d() && myEdgeDivide->HasCurve3d() ) { |
322 | SplitValues2d = theTransferParamTool->Perform(theKnots3d,Standard_True); |
323 | SplitValues3d = theTransferParamTool->Perform(theKnots2d,Standard_False); |
324 | CorrectSplitValues(theKnots3d,theKnots2d,SplitValues2d,SplitValues3d); |
325 | } |
326 | Handle(ShapeUpgrade_SplitCurve3d) theSplit3dTool = myEdgeDivide->GetSplitCurve3dTool(); |
327 | Handle(ShapeUpgrade_SplitCurve2d) theSplit2dTool = myEdgeDivide->GetSplitCurve2dTool(); |
328 | |
329 | if ( myEdgeDivide->HasCurve2d() ) { |
330 | if(! theKnots3d.IsNull() ) { |
331 | SplitValues2d->Remove(1); |
332 | SplitValues2d->Remove(SplitValues2d->Length()); |
333 | theSplit2dTool->SetSplitValues (SplitValues2d); |
334 | } |
335 | theSplit2dTool->Build(Standard_True); |
336 | } |
337 | if ( myEdgeDivide->HasCurve3d() ) { |
338 | if( ! theKnots2d.IsNull() ) { |
339 | SplitValues3d->Remove(1); |
340 | SplitValues3d->Remove(SplitValues3d->Length()); |
341 | theSplit3dTool->SetSplitValues (SplitValues3d); |
342 | } |
343 | theSplit3dTool->Build (Standard_True); |
344 | } |
345 | // get 2d and 3d split values which should be the same |
346 | if ( myEdgeDivide->HasCurve2d() ) theKnots2d = theSplit2dTool->SplitValues(); |
347 | if ( myEdgeDivide->HasCurve3d() ) theKnots3d = theSplit3dTool->SplitValues(); |
348 | |
349 | Standard_Boolean isSeam = Standard_False; |
350 | if (! myFace.IsNull() ) |
351 | isSeam = BRep_Tool::IsClosed ( E, myFace ); |
352 | Handle(TColGeom2d_HArray1OfCurve) theSegments2d; |
353 | if(myEdgeDivide->HasCurve2d()) |
354 | theSegments2d = theSplit2dTool->GetCurves(); |
355 | Handle(TColGeom2d_HArray1OfCurve) theSegments2dR; |
356 | if ( isSeam ) { |
357 | Handle(Geom2d_Curve) c2; |
358 | Standard_Real f2, l2; |
359 | //smh#8 |
360 | TopoDS_Shape tmpE = E.Reversed(); |
361 | TopoDS_Edge erev = TopoDS::Edge (tmpE ); |
362 | if ( sae.PCurve ( erev, myFace, c2, f2, l2, Standard_False) ) { |
363 | theSplit2dTool->Init (c2, f2, l2); |
364 | if(!theKnots2d.IsNull()) |
365 | theSplit2dTool->SetSplitValues (theKnots2d); |
366 | theSplit2dTool->Perform (Standard_True); |
367 | Handle(TColStd_HSequenceOfReal) revKnots2d = theSplit2dTool->SplitValues(); |
dede2e21 |
368 | if(revKnots2d->Length()!=theKnots2d->Length()) { |
7fd59977 |
369 | isSeam = Standard_False; |
63c629aa |
370 | #ifdef SHAPEUPGRADE_DEB |
7fd59977 |
371 | cout << "Error: ShapeUpgrade_WireDivide: seam has different splitting values on pcurvesd" << endl; |
372 | #endif |
373 | } |
374 | else |
375 | theSegments2dR = theSplit2dTool->GetCurves(); |
376 | } |
377 | else isSeam = Standard_False; |
378 | } |
379 | |
380 | // Exploring theEdge |
381 | TopoDS_Vertex V1o = TopExp::FirstVertex (E, Standard_False); |
382 | TopoDS_Vertex V2o = TopExp::LastVertex (E, Standard_False); |
383 | Standard_Boolean isForward = ( E.Orientation() == TopAbs_FORWARD ); |
384 | Standard_Real TolEdge = BRep_Tool::Tolerance (E); |
385 | Standard_Boolean isDeg = BRep_Tool::Degenerated ( E ); |
386 | |
387 | // Copy vertices to protect original shape against SameParamseter |
388 | //smh#8 |
389 | TopoDS_Shape emptyCopiedV1 = V1o.EmptyCopied(); |
390 | TopoDS_Vertex V1 = TopoDS::Vertex ( emptyCopiedV1 ); |
391 | Context()->Replace ( V1o, V1 ); |
392 | TopoDS_Vertex V2; |
393 | if ( V1o.IsSame ( V2o ) ) { |
394 | //smh#8 |
395 | TopoDS_Shape tmpV = V1.Oriented(V2o.Orientation() ); |
396 | V2 = TopoDS::Vertex ( tmpV ); |
397 | } |
398 | else { |
399 | //smh#8 |
400 | TopoDS_Shape emptyCopied = V2o.EmptyCopied(); |
401 | V2 = TopoDS::Vertex ( emptyCopied ); |
402 | Context()->Replace ( V2o, V2 ); |
403 | } |
404 | |
405 | //collect NM vertices |
406 | |
1d47d8d0 |
407 | Standard_Real af = 0.,al = 0.; |
7fd59977 |
408 | Handle(Geom_Curve) c3d; |
409 | Adaptor3d_CurveOnSurface AdCS; |
410 | if(myEdgeDivide->HasCurve3d()) |
411 | sae.Curve3d(E,c3d,af,al,Standard_False); |
412 | else if(myEdgeDivide->HasCurve2d() && !Surf.IsNull()) { |
413 | Handle(Geom2d_Curve) c2d; |
414 | sae.PCurve ( E, myFace, c2d, af, al, Standard_False); |
415 | Handle(GeomAdaptor_HSurface) AdS = new GeomAdaptor_HSurface(Surf); |
416 | Handle(Geom2dAdaptor_HCurve) AC2d = new Geom2dAdaptor_HCurve(c2d,af,al); |
417 | AdCS.Load(AC2d); |
418 | AdCS.Load(AdS); |
419 | } |
420 | TopTools_SequenceOfShape aSeqNMVertices; |
421 | TColStd_SequenceOfReal aSeqParNM; |
422 | TopoDS_Iterator aItv(E,Standard_False); |
423 | ShapeAnalysis_Curve sac; |
424 | for ( ; aItv.More() ; aItv.Next()) { |
425 | if(aItv.Value().Orientation() == TopAbs_INTERNAL || |
426 | aItv.Value().Orientation() == TopAbs_EXTERNAL) { |
427 | TopoDS_Vertex aVold = TopoDS::Vertex(aItv.Value()); |
428 | aSeqNMVertices.Append(aVold); |
429 | gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(aVold)); |
430 | Standard_Real ppar; |
431 | gp_Pnt pproj; |
432 | if(!c3d.IsNull()) |
433 | sac.Project(c3d,aP,Precision(),pproj,ppar,af,al,Standard_False); |
434 | else |
435 | sac.Project(AdCS,aP,Precision(),pproj,ppar); |
436 | aSeqParNM.Append(ppar); |
437 | } |
438 | } |
439 | |
440 | // creating new edge(s) |
441 | Handle(TColGeom_HArray1OfCurve) theSegments3d; |
442 | if(myEdgeDivide->HasCurve3d()) theSegments3d = theSplit3dTool->GetCurves(); |
443 | |
444 | Standard_Integer nbc = 0; |
445 | if (!theSegments3d.IsNull()) { |
446 | nbc = theSegments3d->Length(); |
447 | if ( !theSegments2d.IsNull() ) { |
448 | Standard_Integer nbc2d = theSegments2d->Length(); |
449 | if (nbc!=nbc2d) { |
63c629aa |
450 | #ifdef SHAPEUPGRADE_DEB |
7fd59977 |
451 | cout<<"Error: Number of intervals are not equal for 2d 3d. Ignored."<<endl; |
452 | #endif |
453 | nbc = Min( nbc,nbc2d); |
454 | } |
455 | } |
456 | } |
457 | else |
458 | if(!theSegments2d.IsNull())// if theSegments have different length ??? |
459 | nbc = theSegments2d->Length(); |
460 | |
461 | if ( nbc <= 1 && ! theSplit3dTool->Status ( ShapeExtend_DONE ) && |
462 | ! theSplit2dTool->Status ( ShapeExtend_DONE ) ) { |
463 | B.Add ( newWire, E ); |
464 | continue; |
465 | } |
466 | |
467 | myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 ); |
468 | |
469 | TopoDS_Wire resWire; |
470 | B.MakeWire (resWire); |
471 | // TopoDS_Vertex firstVertex, lastVertex; |
472 | Standard_Integer numE =0; |
473 | gp_Pnt pntV1 = BRep_Tool::Pnt(V1); |
474 | //gp_Pnt pntV2 = BRep_Tool::Pnt(V2); // pntV2 not used - see below (skl) |
7fd59977 |
475 | //Standard_Real V2Tol = LimitTolerance( BRep_Tool::Tolerance(V2) ); // V2Tol not used - see below (skl) |
476 | |
477 | Handle(ShapeUpgrade_FixSmallCurves) FixSmallCurveTool = GetFixSmallCurveTool(); //gka Precision |
478 | FixSmallCurveTool->SetMinTolerance(MinTolerance()); |
479 | FixSmallCurveTool->Init(E, myFace); |
480 | FixSmallCurveTool->SetSplitCurve3dTool(theSplit3dTool); |
481 | FixSmallCurveTool->SetSplitCurve2dTool(theSplit2dTool); |
482 | FixSmallCurveTool->SetPrecision(MinTolerance()); |
483 | Standard_Integer Savnum =0; |
484 | Standard_Real SavParf; |
485 | Standard_Integer Small = 0; |
486 | for ( Standard_Integer icurv = 1; icurv <= nbc; icurv++ ) { |
487 | |
488 | Handle(Geom_Curve) theNewCurve3d; |
489 | if(!theSegments3d.IsNull()) theNewCurve3d = theSegments3d->Value(icurv); |
490 | |
491 | Handle(Geom2d_Curve) theNewPCurve1; |
492 | if(!theSegments2d.IsNull()) theNewPCurve1 = theSegments2d->Value(icurv); |
493 | Handle(Geom2d_Curve) revPCurve; |
494 | if(isSeam) |
495 | revPCurve = theSegments2dR->Value(icurv); |
496 | // construction of the intermediate Vertex |
497 | TopoDS_Vertex V; |
498 | if ( icurv <= nbc && nbc != 1 && ! isDeg ) { |
499 | Standard_Real par,parf /*,SavParl*/; |
500 | //Standard_Real SaveParf; // SaveParf not used - see below (skl) |
501 | gp_Pnt P,P1,PM; |
502 | // if edge has 3d curve, take point from it |
503 | if ( ! theNewCurve3d.IsNull() ) { |
504 | if(theNewCurve3d->IsKind(STANDARD_TYPE(Geom_BoundedCurve))) { |
505 | par = theNewCurve3d->LastParameter(); |
506 | parf = theNewCurve3d->FirstParameter(); |
507 | } |
508 | else { |
509 | par = theKnots3d->Value (icurv + 1); |
510 | parf = theKnots3d->Value (icurv); |
511 | } |
512 | P = theNewCurve3d->Value (par); |
513 | P1 = theNewCurve3d->Value (parf); |
514 | PM = theNewCurve3d->Value ((parf+par)/2); |
515 | } |
516 | // else use pcurve and surface (suppose that both exist) |
517 | else { |
518 | if ( Surf.IsNull() ) Surf = BRep_Tool::Surface ( myFace, Loc ); |
519 | if ( theNewPCurve1->IsKind(STANDARD_TYPE(Geom2d_BoundedCurve)) ) { |
520 | par = theNewPCurve1->LastParameter(); |
521 | parf = theNewPCurve1->FirstParameter(); |
522 | } |
523 | else { |
524 | par = theKnots2d->Value (icurv + 1); |
525 | parf = theKnots2d->Value (icurv); |
526 | } |
527 | gp_Pnt2d p2d = theNewPCurve1->Value (par); |
528 | gp_Pnt2d p2df = theNewPCurve1->Value (parf); |
529 | gp_Pnt2d p2dM = theNewPCurve1->Value ((parf+par)/2); |
530 | P = Surf->Value ( p2d.X(), p2d.Y() ); |
531 | P1 = Surf->Value ( p2df.X(), p2df.Y() ); |
532 | PM = Surf->Value ( p2dM.X(), p2dM.Y() ); |
533 | P.Transform ( Loc.Transformation() ); |
534 | P1.Transform ( Loc.Transformation() ); |
535 | PM.Transform ( Loc.Transformation() ); |
536 | } |
537 | if(P.Distance(pntV1) < MinTolerance() && P.Distance(PM) < MinTolerance() && !myFace.IsNull()) { |
538 | if(!Small) { |
539 | SavParf = parf; |
540 | Savnum = icurv; |
541 | } |
542 | //SavParl = par; |
543 | Small++; |
544 | if(icurv == nbc) { |
545 | TopoDS_Vertex VVV = V1; |
546 | VVV.Orientation ( V2.Orientation() ); |
547 | Context()->Replace(V2,VVV); |
548 | } |
549 | continue; |
550 | } |
551 | if(Small) { |
552 | if(P.Distance(P1) > MinTolerance() || P.Distance(PM) > MinTolerance()) { |
553 | //FixSmallCurveTool->Perform(prevEdge,theNewCurve3d,theNewPCurve1,revPCurve,SavParf,SavParl); |
554 | gp_Pnt pmid = 0.5 * ( pntV1.XYZ() + P1.XYZ() ); |
555 | B.UpdateVertex(V1,pmid,0); |
556 | } |
557 | else { |
558 | Handle(Geom_Curve) atmpCurve; |
559 | Handle(Geom2d_Curve) atmpCurve2d1,atmprepcurve; |
560 | if(FixSmallCurveTool->Approx( atmpCurve,atmpCurve2d1,atmprepcurve,SavParf,par)) { //BRepTools |
561 | theNewCurve3d = atmpCurve; |
562 | theNewPCurve1 = atmpCurve2d1; |
563 | revPCurve = atmprepcurve; |
564 | } |
565 | else { |
566 | gp_Pnt pmid = 0.5 * ( pntV1.XYZ() + P1.XYZ() ); |
567 | B.UpdateVertex(V1,pmid,0); |
568 | } |
569 | } |
570 | Small =0; |
571 | } |
572 | //pdn |
573 | /* if(P.Distance (pntV1) < V1Tol) |
574 | V = V1; |
575 | else if (P.Distance (pntV2) < V2Tol) { |
576 | V = V2; |
577 | V1Tol = V2Tol; |
578 | pntV1 = pntV2; |
579 | } |
580 | else {*/ |
581 | if(icurv != nbc) { |
582 | B.MakeVertex (V, P, TolEdge); //tolerance of the edge |
583 | pntV1 = P; |
7fd59977 |
584 | } |
585 | else V = V2; |
586 | // else V2; |
587 | // } |
588 | // if (ShapeUpgrade::Debug()) cout <<"... New intermediate Vertex (" |
589 | // <<P.X()<<","<<P.Y()<<","<<P.Z()<<") :"<<(void*) &(*V.TShape()) |
590 | // <<" with Tolerance "<<TolEdge <<endl; |
591 | } |
592 | //else V = V2; |
593 | |
594 | TopoDS_Edge newEdge; |
595 | ShapeBuild_Edge sbe; |
596 | if ( isForward ) { |
597 | V1.Orientation ( TopAbs_FORWARD ); |
598 | V.Orientation ( TopAbs_REVERSED ); |
599 | newEdge = sbe.CopyReplaceVertices ( E, V1, V ); |
600 | } |
601 | else { |
602 | V1.Orientation ( TopAbs_REVERSED ); |
603 | V.Orientation ( TopAbs_FORWARD ); |
604 | newEdge = sbe.CopyReplaceVertices ( E, V, V1 ); |
605 | } |
606 | sbe.CopyPCurves ( newEdge, E ); |
607 | if(!theNewCurve3d.IsNull()) |
608 | B.UpdateEdge ( newEdge, theNewCurve3d, 0. ); |
609 | else if ( isDeg ) |
610 | B.Degenerated( newEdge, Standard_True); |
611 | //if(isSeam) { |
612 | // Handle(Geom2d_Curve) revPCurve = theSegments2dR->Value(icurv); |
613 | //if(newEdge.Orientation()==TopAbs_FORWARD) |
614 | //B.UpdateEdge ( newEdge, theNewPCurve1, revPCurve, myFace, 0. ); |
615 | //else |
616 | //B.UpdateEdge ( newEdge, revPCurve, theNewPCurve1, myFace, 0. ); |
617 | //} |
618 | //else if ( ! myFace.IsNull() ) |
619 | //B.UpdateEdge ( newEdge, theNewPCurve1, myFace, 0. ); |
620 | |
621 | Standard_Real f3d = 0., l3d =0.; |
622 | if(!Savnum) Savnum = icurv; |
623 | Standard_Boolean srNew; |
624 | if(!theNewCurve3d.IsNull()) { |
625 | if(theNewCurve3d->IsKind(STANDARD_TYPE(Geom_BoundedCurve))) { |
626 | f3d = theNewCurve3d->FirstParameter(); |
627 | l3d = theNewCurve3d->LastParameter(); |
628 | srNew = ((f3d == theKnots3d->Value (Savnum)) && (l3d == theKnots3d->Value (icurv + 1))); |
629 | } |
630 | else { |
631 | f3d = theKnots3d->Value (Savnum); |
632 | l3d = theKnots3d->Value (icurv + 1); |
633 | srNew = Standard_True; |
634 | } |
635 | } |
636 | else |
637 | srNew = Standard_True; |
638 | |
639 | Standard_Real f2d=0, l2d=0; |
640 | if(!theNewPCurve1.IsNull()){ |
641 | if(theNewPCurve1->IsKind(STANDARD_TYPE(Geom2d_BoundedCurve))) { |
642 | f2d = theNewPCurve1->FirstParameter(); |
643 | l2d = theNewPCurve1->LastParameter(); |
644 | srNew &= ((f2d == theKnots2d->Value (Savnum)) && (l2d == theKnots2d->Value (icurv + 1))); |
645 | } |
646 | else { |
647 | f2d = theKnots2d->Value (Savnum); |
648 | l2d = theKnots2d->Value (icurv + 1); |
649 | } |
650 | } |
651 | //if(!Savnum) Savnum = icurv; |
652 | if(!theNewCurve3d.IsNull()) |
653 | theTransferParamTool->TransferRange(newEdge,theKnots3d->Value (Savnum),theKnots3d->Value (icurv + 1),Standard_False); |
654 | else |
655 | theTransferParamTool->TransferRange(newEdge,theKnots2d->Value (Savnum),theKnots2d->Value (icurv + 1),Standard_True); |
656 | /* |
657 | Standard_Real alpha = (theKnots3d->Value (icurv) - f)/(l - f); |
658 | Standard_Real beta = (theKnots3d->Value (icurv + 1) - f)/(l - f); |
659 | sbe.CopyRanges(newEdge,E, alpha, beta);*/ |
660 | Savnum =0; |
661 | Handle(Geom2d_Curve) c2dTmp; |
662 | Standard_Real setF, setL; |
663 | if( ! myFace.IsNull() && sae.PCurve (newEdge, myFace, c2dTmp, setF, setL, Standard_False)) |
664 | srNew &= ( (setF==f2d) && (setL==l2d) ); |
665 | |
666 | if(isSeam) { |
667 | // Handle(Geom2d_Curve revPCurve = theSegments2dR->Value(icurv); |
668 | if(newEdge.Orientation()==TopAbs_FORWARD) |
669 | B.UpdateEdge ( newEdge, theNewPCurve1, revPCurve, myFace, 0. ); |
670 | else |
671 | B.UpdateEdge ( newEdge, revPCurve, theNewPCurve1, myFace, 0. ); |
672 | } |
673 | else if ( ! myFace.IsNull() ) { |
674 | B.UpdateEdge ( newEdge, theNewPCurve1, myFace, 0. ); |
675 | } |
676 | |
677 | if(!theNewCurve3d.IsNull()) |
678 | sbe.SetRange3d(newEdge,f3d,l3d); |
679 | if(!theNewPCurve1.IsNull()) |
680 | B.Range ( newEdge, myFace, f2d, l2d); |
681 | if((!wasSR || !srNew)&&!BRep_Tool::Degenerated(newEdge) ) |
682 | B.SameRange(newEdge, Standard_False); |
683 | |
684 | //addition NM vertices to new edges |
685 | Standard_Real afpar = (myEdgeDivide->HasCurve3d() ? f3d : f2d); |
686 | |
687 | Standard_Real alpar = (myEdgeDivide->HasCurve3d() ? l3d: l2d); |
688 | Standard_Integer n =1; |
689 | for( ; n <= aSeqParNM.Length(); n++) { |
690 | Standard_Real apar = aSeqParNM.Value(n); |
691 | TopoDS_Vertex aVold = TopoDS::Vertex(aSeqNMVertices.Value(n)); |
692 | TopoDS_Vertex aNMVer =ShapeAnalysis_TransferParametersProj::CopyNMVertex(aVold,newEdge,E); |
693 | Context()->Replace(aVold,aNMVer); |
694 | if(fabs(apar - afpar) <= Precision::PConfusion()) |
695 | Context()->Replace(aNMVer,V1); |
696 | else if(fabs(apar - alpar) <= Precision::PConfusion()) |
697 | Context()->Replace(aNMVer,V); |
698 | else if( apar > afpar && apar <alpar) |
699 | B.Add (newEdge,aNMVer); |
700 | else continue; |
701 | aSeqNMVertices.Remove(n); |
702 | aSeqParNM.Remove(n); |
703 | n--; |
704 | } |
705 | |
706 | |
707 | // if (ShapeUpgrade::Debug()) cout <<"... New Edge " |
708 | // <<(void*) &(*newEdge.TShape())<<" on vertices " |
709 | // <<(void*) &(*V1.TShape())<<", " <<(void*) &(*V.TShape()) |
710 | // <<" with Tolerance "<<TolEdge <<endl; |
711 | B.Add ( resWire, newEdge ); |
712 | B.Add ( newWire, newEdge ); |
713 | numE++; |
714 | V1 = V; |
715 | } |
716 | if(numE) |
ab860031 |
717 | { |
718 | resWire.Closed (BRep_Tool::IsClosed (resWire)); |
7fd59977 |
719 | Context()->Replace(E,resWire); |
ab860031 |
720 | } |
7fd59977 |
721 | else |
722 | Context()->Remove(E); |
723 | } |
724 | } |
725 | if ( Status ( ShapeExtend_DONE ) ) { |
726 | //smh#8 |
ab860031 |
727 | newWire.Closed (BRep_Tool::IsClosed (newWire)); |
7fd59977 |
728 | TopoDS_Shape tmpW = Context()->Apply ( newWire ).Oriented(myWire.Orientation()); |
729 | myWire = TopoDS::Wire (tmpW ); |
730 | } |
731 | } |
732 | |
733 | //======================================================================= |
734 | //function : Face |
735 | //purpose : |
736 | //======================================================================= |
737 | |
738 | const TopoDS_Wire& ShapeUpgrade_WireDivide::Wire() const |
739 | { |
740 | return myWire; |
741 | } |
742 | |
743 | //======================================================================= |
744 | //function : Status |
745 | //purpose : |
746 | //======================================================================= |
747 | |
748 | Standard_Boolean ShapeUpgrade_WireDivide::Status (const ShapeExtend_Status status) const |
749 | { |
750 | return ShapeExtend::DecodeStatus ( myStatus, status ); |
751 | } |
752 | |
753 | //======================================================================= |
754 | //function : SetSplitCurve3dTool |
755 | //purpose : |
756 | //======================================================================= |
757 | |
758 | void ShapeUpgrade_WireDivide::SetSplitCurve3dTool(const Handle(ShapeUpgrade_SplitCurve3d)& splitCurve3dTool) |
759 | { |
760 | mySplitCurve3dTool = splitCurve3dTool; |
761 | } |
762 | |
763 | //======================================================================= |
764 | //function : SetSplitCurve2dTool |
765 | //purpose : |
766 | //======================================================================= |
767 | |
768 | void ShapeUpgrade_WireDivide::SetSplitCurve2dTool(const Handle(ShapeUpgrade_SplitCurve2d)& splitCurve2dTool) |
769 | { |
770 | mySplitCurve2dTool = splitCurve2dTool; |
771 | } |
772 | |
773 | //======================================================================= |
774 | //function : GetSplitCurve3dTool |
775 | //purpose : |
776 | //======================================================================= |
777 | |
778 | Handle(ShapeUpgrade_SplitCurve3d) ShapeUpgrade_WireDivide::GetSplitCurve3dTool() const |
779 | { |
780 | return mySplitCurve3dTool; |
781 | } |
782 | |
783 | //======================================================================= |
784 | //function : GetSplitCurve2dTool |
785 | //purpose : |
786 | //======================================================================= |
787 | |
788 | Handle(ShapeUpgrade_SplitCurve2d) ShapeUpgrade_WireDivide::GetSplitCurve2dTool() const |
789 | { |
790 | return mySplitCurve2dTool; |
791 | } |
792 | |
793 | //======================================================================= |
794 | //function : SetEdgeDivideTool |
795 | //purpose : |
796 | //======================================================================= |
797 | |
798 | void ShapeUpgrade_WireDivide::SetEdgeDivideTool(const Handle (ShapeUpgrade_EdgeDivide)& edgeDivideTool) |
799 | { |
800 | myEdgeDivide = edgeDivideTool; |
801 | } |
802 | |
803 | //======================================================================= |
804 | //function : GetEdgeDivideTool |
805 | //purpose : |
806 | //======================================================================= |
807 | |
808 | Handle (ShapeUpgrade_EdgeDivide) ShapeUpgrade_WireDivide::GetEdgeDivideTool() const |
809 | { |
810 | return myEdgeDivide; |
811 | } |
812 | |
813 | //======================================================================= |
814 | //function : SetTransferParamTool |
815 | //purpose : |
816 | //======================================================================= |
817 | |
818 | void ShapeUpgrade_WireDivide::SetTransferParamTool(const Handle(ShapeAnalysis_TransferParameters)& TransferParam) |
819 | { |
820 | myTransferParamTool = TransferParam; |
821 | } |
822 | |
823 | //======================================================================= |
824 | //function : GetTransferParamTool |
825 | //purpose : |
826 | //======================================================================= |
827 | |
828 | Handle(ShapeAnalysis_TransferParameters) ShapeUpgrade_WireDivide::GetTransferParamTool() |
829 | { |
830 | return myTransferParamTool; |
831 | } |
832 | |
833 | //======================================================================= |
834 | //function : SetEdgeMode |
835 | //purpose : |
836 | //======================================================================= |
837 | |
838 | void ShapeUpgrade_WireDivide::SetEdgeMode(const Standard_Integer EdgeMode) |
839 | { |
840 | myEdgeMode = EdgeMode; |
841 | } |
842 | |
843 | //======================================================================= |
844 | //function : SetFixSmallCurveTool |
845 | //purpose : |
846 | //======================================================================= |
847 | |
848 | void ShapeUpgrade_WireDivide::SetFixSmallCurveTool(const Handle(ShapeUpgrade_FixSmallCurves)& FixSmallCurvesTool) |
849 | { |
850 | myFixSmallCurveTool = FixSmallCurvesTool; |
851 | } |
852 | |
853 | //======================================================================= |
854 | //function : GetFixSmallCurveTool |
855 | //purpose : |
856 | //======================================================================= |
857 | |
858 | Handle(ShapeUpgrade_FixSmallCurves) ShapeUpgrade_WireDivide::GetFixSmallCurveTool() const |
859 | { |
860 | return myFixSmallCurveTool; |
861 | } |