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