7fd59977 |
1 | // File: XDEDRAW_Props.cxx |
2 | // Created: Fri Aug 4 14:38:55 2000 |
3 | // Author: Pavel TELKOV |
4 | // <ptv@zamox.nnov.matra-dtv.fr> |
5 | // OCC532 sln 24.07.2002. Add epsilon parameter to SetProps function |
6 | |
7 | #include <XDEDRAW_Props.ixx> |
8 | |
9 | #include <DBRep.hxx> |
10 | #include <DDocStd.hxx> |
11 | |
12 | #include <TCollection_AsciiString.hxx> |
13 | #include <TopoDS_Shape.hxx> |
14 | |
15 | #include <GProp_GProps.hxx> |
16 | #include <BRepGProp.hxx> |
17 | |
18 | #include <TDF_Tool.hxx> |
19 | #include <TDF_Label.hxx> |
20 | #include <TDF_LabelSequence.hxx> |
21 | #include <TDocStd_Document.hxx> |
22 | #include <TDataStd_Name.hxx> |
23 | |
24 | #include <XCAFDoc_DocumentTool.hxx> |
25 | #include <XCAFDoc_ShapeTool.hxx> |
26 | #include <XCAFDoc_Area.hxx> |
27 | #include <XCAFDoc_Volume.hxx> |
28 | #include <XCAFDoc_Centroid.hxx> |
29 | #include <XCAFDoc_MaterialTool.hxx> |
30 | #include <XCAFDoc_Location.hxx> |
31 | #include <Precision.hxx> |
32 | #include <TNaming_NamedShape.hxx> |
33 | |
34 | #include <Standard_ErrorHandler.hxx> |
35 | #include <Standard_Failure.hxx> |
36 | #include <gp_Pln.hxx> |
37 | #include <BRepMesh.hxx> |
38 | #include <TColgp_Array1OfPnt.hxx> |
39 | #include <Poly_Triangulation.hxx> |
40 | #include <TopoDS_Compound.hxx> |
41 | #include <TopExp_Explorer.hxx> |
42 | #include <TopoDS_Face.hxx> |
43 | #include <TopoDS.hxx> |
44 | #include <BRep_Tool.hxx> |
45 | #include <BRepMesh_IncrementalMesh.hxx> |
46 | #include <TopoDS_Vertex.hxx> |
47 | #include <Standard_Stream.hxx> |
48 | #include <stdio.h> |
49 | #include <TColgp_Array1OfXYZ.hxx> |
50 | #include <TColStd_Array1OfReal.hxx> |
51 | #include <TDataStd_TreeNode.hxx> |
52 | #include <XCAFDoc.hxx> |
53 | #include <TCollection_HAsciiString.hxx> |
54 | |
55 | |
56 | // --------------------- VolumeFix Begin --- |
57 | |
58 | //======================================================================= |
59 | //function : TetraVol |
60 | //purpose : auxilary |
61 | //======================================================================= |
62 | static double TetraVol(gp_Pnt RefPoint, gp_Pnt Som1, gp_Pnt Som2, gp_Pnt Som3) |
63 | { |
64 | double curVolume = 0; |
65 | gp_Dir Line12; |
66 | gp_Pln Plane123; |
67 | gp_Vec N; |
68 | |
69 | { |
70 | try |
71 | { |
72 | OCC_CATCH_SIGNALS |
73 | Line12=gp_Dir( gp_Vec(Som1, Som2)); |
74 | gp_Vec v1(Som1, Som2); |
75 | gp_Vec v2(Som2, Som3); |
76 | N=v1^v2; |
77 | Plane123=gp_Pln( Som1, gp_Dir( N ) ); |
78 | } |
79 | catch(Standard_Failure) {return(0.);} |
80 | } |
81 | double L1, L2, L3; |
82 | L1 = Som1.Distance(Som2); |
83 | L2 = gp_Lin(Som1, Line12).Distance(Som3); |
84 | L3 = Plane123.Distance(RefPoint); |
85 | |
86 | curVolume = ((L1 * L2)/2) * (L3/3); |
87 | |
88 | gp_Vec Rad(RefPoint, Som1); |
89 | |
90 | if( (Rad*N)>0 ) |
91 | return (curVolume); |
92 | else |
93 | return (-curVolume); |
94 | } |
95 | |
96 | |
97 | //======================================================================= |
98 | //function : TetraCen |
99 | //purpose : auxilary |
100 | //======================================================================= |
101 | static gp_XYZ TetraCen(gp_Pnt RefPoint, gp_Pnt Som1, gp_Pnt Som2, gp_Pnt Som3) |
102 | { |
103 | gp_XYZ curCentr, plnPnt; |
104 | plnPnt = ( Som1.XYZ() + Som2.XYZ() + Som3.XYZ() )/3; |
105 | curCentr = plnPnt + (RefPoint.XYZ() - plnPnt)/4; |
106 | return curCentr; |
107 | } |
108 | |
109 | |
110 | //======================================================================= |
111 | //function : CalculVolume |
112 | //purpose : auxilary |
113 | //======================================================================= |
114 | static Standard_Real CalculVolume(const TopoDS_Shape& So, |
115 | gp_Pnt& aRefPoint, |
116 | Standard_Real tol, |
117 | Standard_Boolean withForce, |
118 | Draw_Interpretor& di) |
119 | { |
120 | Standard_Real myVolume = 0, curVolume = 0; |
121 | gp_XYZ localCentroid(0,0,0), curCentroid(0,0,0); |
122 | Standard_Boolean haveVertex = Standard_False; |
123 | for (TopExp_Explorer ex(So,TopAbs_FACE) ; ex.More(); ex.Next()) |
124 | { |
125 | TopoDS_Face F =TopoDS::Face(ex.Current()); |
126 | TopLoc_Location L; |
127 | if ( ! haveVertex ) |
128 | for (TopExp_Explorer Vex(F, TopAbs_VERTEX); Vex.More(); Vex.Next() ) |
129 | { |
130 | TopoDS_Vertex v = TopoDS::Vertex(Vex.Current()); |
131 | if ( ! v.IsNull() ) { |
132 | aRefPoint = BRep_Tool::Pnt(v); |
133 | haveVertex = Standard_True; |
134 | break; |
135 | } |
136 | } |
137 | |
138 | Handle (Poly_Triangulation) facing = BRep_Tool::Triangulation(F,L); |
139 | if(facing.IsNull() || withForce) |
140 | { |
141 | // BRepMesh::Mesh(F, tol); |
142 | BRepMesh_IncrementalMesh MESH(F, tol); |
143 | |
144 | facing = BRep_Tool::Triangulation(F,L); |
145 | } |
146 | |
147 | TColgp_Array1OfPnt tab(1,(facing->NbNodes())); |
148 | tab = facing->Nodes(); |
149 | Poly_Array1OfTriangle tri(1,facing->NbTriangles()); |
150 | tri = facing->Triangles(); |
151 | for (Standard_Integer i=1;i<=(facing->NbTriangles());i++) |
152 | { |
153 | |
154 | Poly_Triangle trian = tri.Value(i); |
155 | Standard_Integer index1,index2,index3;//M,N; |
156 | if( F.Orientation() == TopAbs_REVERSED ) |
157 | trian.Get(index1,index3,index2); |
158 | else |
159 | trian.Get(index1,index2,index3); |
160 | curVolume = TetraVol(aRefPoint, tab.Value(index1), |
161 | tab.Value(index2), tab.Value(index3)); |
162 | myVolume += curVolume; |
163 | curCentroid = TetraCen(aRefPoint, tab.Value(index1), |
164 | tab.Value(index2), tab.Value(index3)); |
165 | |
166 | localCentroid = localCentroid + curCentroid*curVolume; |
167 | } |
168 | } |
169 | |
170 | localCentroid = localCentroid * (1./ myVolume); |
171 | |
172 | di << "Centroid:" << "\n"; |
173 | di << "X=\t" << localCentroid.X() << "\n"; |
174 | di << "Y=\t" << localCentroid.Y() << "\n"; |
175 | di << "Z=\t" << localCentroid.Z() << "\n"; |
176 | return (myVolume); |
177 | } |
178 | |
179 | |
180 | // --------------------- VolumeFix End --- |
181 | |
182 | |
183 | //======================================================================= |
184 | // Section: Work with val props |
185 | //======================================================================= |
186 | |
187 | //======================================================================= |
188 | //function : SetProps |
189 | //purpose : |
190 | //======================================================================= |
191 | |
192 | static Standard_Integer SetProps (Draw_Interpretor& di, Standard_Integer argc, const char** argv) |
193 | { |
194 | if (argc < 3) { |
195 | di<<"Use: "<<argv[0]<<" DocName {Shape|Label} [epsilon = 0.001]"<<"\n"; |
196 | return 1; |
197 | } |
198 | Handle(TDocStd_Document) Doc; |
199 | DDocStd::GetDocument(argv[1], Doc); |
200 | if ( Doc.IsNull() ) { di << argv[1] << " is not a document" << "\n"; return 1; } |
201 | |
202 | Standard_Real Vres, Ares; |
203 | |
204 | TDF_Label aLabel; |
205 | TDF_Tool::Label(Doc->GetData(), argv[2], aLabel); |
206 | TopoDS_Shape aShape; |
207 | if ( aLabel.IsNull() ) { |
208 | aShape= DBRep::Get(argv[2]); |
209 | if ( !aShape.IsNull() ) { |
210 | Handle(XCAFDoc_ShapeTool) STool = XCAFDoc_DocumentTool::ShapeTool(Doc->Main()); |
211 | aLabel = STool->FindShape(aShape); |
212 | } |
213 | } |
214 | else { |
215 | aShape = XCAFDoc_ShapeTool::GetShape ( aLabel ); |
216 | } |
217 | if ( !aLabel.IsNull() ) { |
218 | |
219 | // retrieve epsilon |
220 | Standard_Real anEps; |
221 | if(argc > 3 ) anEps = atof(argv[3]); |
222 | else anEps = 0.001; |
223 | |
224 | GProp_GProps G; |
225 | BRepGProp::VolumeProperties(aShape,G,anEps,Standard_True); |
226 | Vres = G.Mass(); |
227 | Handle(XCAFDoc_Volume) aVolume = new XCAFDoc_Volume; |
228 | if (!aLabel.FindAttribute (XCAFDoc_Volume::GetID(), aVolume)) aLabel.AddAttribute(aVolume); |
229 | aVolume->Set(Vres); |
230 | |
231 | gp_Pnt aPoint = G.CentreOfMass(); |
232 | Handle(XCAFDoc_Centroid) aCentroid = new XCAFDoc_Centroid; |
233 | if (!aLabel.FindAttribute (XCAFDoc_Centroid::GetID(), aCentroid)) aLabel.AddAttribute(aCentroid); |
234 | aCentroid->Set(aPoint); |
235 | |
236 | BRepGProp::SurfaceProperties(aShape,G,anEps); |
237 | Ares = G.Mass(); |
238 | Handle(XCAFDoc_Area) aArea = new XCAFDoc_Area; |
239 | if (!aLabel.FindAttribute (XCAFDoc_Area::GetID(), aArea)) aLabel.AddAttribute(aArea); |
240 | aArea->Set(Ares); |
241 | |
242 | di << argv[2] << ": Volume = " << Vres << ", Area = " << Ares << |
243 | ", Centroid is (" << aPoint.X() << ", " << aPoint.Y() << ", " << aPoint.Z() << ")"; |
244 | } |
245 | return 0; |
246 | } |
247 | |
248 | |
249 | //======================================================================= |
250 | //function : SetVolume |
251 | //purpose : |
252 | //======================================================================= |
253 | |
254 | static Standard_Integer SetVolume (Draw_Interpretor& di, Standard_Integer argc, const char** argv) |
255 | { |
256 | if (argc!=4) { |
257 | di<<"Use: "<<argv[0]<<" DocName {Label|Shape} volume"<<"\n"; |
258 | return 1; |
259 | } |
260 | Handle(TDocStd_Document) Doc; |
261 | DDocStd::GetDocument(argv[1], Doc); |
262 | if ( Doc.IsNull() ) { di << argv[1] << " is not a document" << "\n"; return 1; } |
263 | |
264 | Standard_Real res=0.; |
265 | |
266 | TDF_Label aLabel; |
267 | TDF_Tool::Label(Doc->GetData(), argv[2], aLabel); |
268 | if ( aLabel.IsNull() ) { |
269 | TopoDS_Shape aShape= DBRep::Get(argv[2]); |
270 | if ( !aShape.IsNull() ) { |
271 | Handle(XCAFDoc_ShapeTool) STool = XCAFDoc_DocumentTool::ShapeTool(Doc->Main()); |
272 | aLabel = STool->FindShape(aShape); |
273 | } |
274 | } |
275 | if ( !aLabel.IsNull() ) { |
276 | res = atof(argv[3]); |
277 | Handle(XCAFDoc_Volume) aVolume = new XCAFDoc_Volume; |
278 | if (!aLabel.FindAttribute (XCAFDoc_Volume::GetID(), aVolume)) aLabel.AddAttribute(aVolume); |
279 | aVolume->Set(res); |
280 | } |
281 | |
282 | di << res; |
283 | return 0; |
284 | } |
285 | |
286 | |
287 | //======================================================================= |
288 | //function : SetArea |
289 | //purpose : |
290 | //======================================================================= |
291 | |
292 | static Standard_Integer SetArea (Draw_Interpretor& di, Standard_Integer argc, const char** argv) |
293 | { |
294 | if (argc!=4) { |
295 | di<<"Use: "<<argv[0]<<" DocName {Label|Shape} area"<<"\n"; |
296 | return 1; |
297 | } |
298 | Handle(TDocStd_Document) Doc; |
299 | DDocStd::GetDocument(argv[1], Doc); |
300 | if ( Doc.IsNull() ) { di << argv[1] << " is not a document" << "\n"; return 1; } |
301 | |
302 | Standard_Real res=0.; |
303 | |
304 | TDF_Label aLabel; |
305 | TDF_Tool::Label(Doc->GetData(), argv[2], aLabel); |
306 | if ( aLabel.IsNull() ) { |
307 | TopoDS_Shape aShape= DBRep::Get(argv[2]); |
308 | if ( !aShape.IsNull() ) { |
309 | Handle(XCAFDoc_ShapeTool) STool = XCAFDoc_DocumentTool::ShapeTool(Doc->Main()); |
310 | aLabel = STool->FindShape(aShape); |
311 | } |
312 | } |
313 | if ( !aLabel.IsNull() ) { |
314 | res = atof(argv[3]); |
315 | Handle(XCAFDoc_Area) aArea = new XCAFDoc_Area; |
316 | if (!aLabel.FindAttribute (XCAFDoc_Area::GetID(), aArea)) aLabel.AddAttribute(aArea); |
317 | aArea->Set(res); |
318 | } |
319 | di << res; |
320 | return 0; |
321 | } |
322 | |
323 | |
324 | //======================================================================= |
325 | //function : SetCentroid |
326 | //purpose : |
327 | //======================================================================= |
328 | |
329 | static Standard_Integer SetCentroid (Draw_Interpretor& di, Standard_Integer argc, const char** argv) |
330 | { |
331 | if (argc!=6) { |
332 | di<<"Use: "<<argv[0]<<" DocName {Label|Shape} x y z"<<"\n"; |
333 | return 1; |
334 | } |
335 | Handle(TDocStd_Document) Doc; |
336 | DDocStd::GetDocument(argv[1], Doc); |
337 | if ( Doc.IsNull() ) { di << argv[1] << " is not a document" << "\n"; return 1; } |
338 | |
339 | gp_Pnt aPoint; |
340 | |
341 | TDF_Label aLabel; |
342 | TDF_Tool::Label(Doc->GetData(), argv[2], aLabel); |
343 | if ( aLabel.IsNull() ) { |
344 | TopoDS_Shape aShape= DBRep::Get(argv[2]); |
345 | if ( !aShape.IsNull() ) { |
346 | Handle(XCAFDoc_ShapeTool) STool = XCAFDoc_DocumentTool::ShapeTool(Doc->Main()); |
347 | aLabel = STool->FindShape(aShape); |
348 | } |
349 | } |
350 | if ( !aLabel.IsNull() ) { |
351 | aPoint.SetX(atof(argv[3])); |
352 | aPoint.SetY(atof(argv[4])); |
353 | aPoint.SetZ(atof(argv[5])); |
354 | Handle(XCAFDoc_Centroid) aCentroid = new XCAFDoc_Centroid; |
355 | if (!aLabel.FindAttribute (XCAFDoc_Centroid::GetID(), aCentroid)) aLabel.AddAttribute(aCentroid); |
356 | aCentroid->Set(aPoint); |
357 | di << atof(argv[3])<<" "<<atof(argv[4])<<" "<<atof(argv[5]); |
358 | } |
359 | return 0; |
360 | } |
361 | |
362 | |
363 | //======================================================================= |
364 | //function : GetVolume |
365 | //purpose : |
366 | //======================================================================= |
367 | |
368 | static Standard_Integer GetVolume (Draw_Interpretor& di, Standard_Integer argc, const char** argv) |
369 | { |
370 | if (argc!=3) { |
371 | di<<"Use: "<<argv[0]<<" DocName {Shape|Label}"<<"\n"; |
372 | return 1; |
373 | } |
374 | Handle(TDocStd_Document) Doc; |
375 | DDocStd::GetDocument(argv[1], Doc); |
376 | if ( Doc.IsNull() ) { di << argv[1] << " is not a document" << "\n"; return 1; } |
377 | |
378 | TDF_Label aLabel; |
379 | TDF_Tool::Label(Doc->GetData(), argv[2], aLabel); |
380 | if ( aLabel.IsNull() ) { |
381 | TopoDS_Shape aShape= DBRep::Get(argv[2]); |
382 | if ( !aShape.IsNull() ) { |
383 | Handle(XCAFDoc_ShapeTool) STool = XCAFDoc_DocumentTool::ShapeTool(Doc->Main()); |
384 | aLabel = STool->FindShape(aShape); |
385 | } |
386 | } |
387 | if ( !aLabel.IsNull() ) { |
388 | // Handle(XCAFDoc_Volume) aVolume = new (XCAFDoc_Volume); |
389 | // if (aLabel.FindAttribute (XCAFDoc_Volume::GetID(), aVolume)) di << aVolume->Get(); |
390 | // another case |
391 | Standard_Real aVol; |
392 | if(XCAFDoc_Volume::Get(aLabel, aVol)) |
393 | di << aVol; |
394 | } |
395 | return 0; |
396 | } |
397 | |
398 | |
399 | //======================================================================= |
400 | //function : GetArea |
401 | //purpose : |
402 | //======================================================================= |
403 | |
404 | static Standard_Integer GetArea (Draw_Interpretor& di, Standard_Integer argc, const char** argv) |
405 | { |
406 | if (argc!=3) { |
407 | di<<"Use: "<<argv[0]<<" DocName {Shape|Label}"<<"\n"; |
408 | return 1; |
409 | } |
410 | Handle(TDocStd_Document) Doc; |
411 | DDocStd::GetDocument(argv[1], Doc); |
412 | if ( Doc.IsNull() ) { di << argv[1] << " is not a document" << "\n"; return 1; } |
413 | |
414 | TDF_Label aLabel; |
415 | TDF_Tool::Label(Doc->GetData(), argv[2], aLabel); |
416 | if ( aLabel.IsNull() ) { |
417 | TopoDS_Shape aShape= DBRep::Get(argv[2]); |
418 | if ( !aShape.IsNull() ) { |
419 | Handle(XCAFDoc_ShapeTool) STool = XCAFDoc_DocumentTool::ShapeTool(Doc->Main()); |
420 | aLabel = STool->FindShape(aShape); |
421 | } |
422 | } |
423 | if ( !aLabel.IsNull() ) { |
424 | // Handle(XCAFDoc_Area) aArea = new (XCAFDoc_Area); |
425 | // if (aLabel.FindAttribute (XCAFDoc_Area::GetID(), aArea)) di << aArea->Get(); |
426 | // another case |
427 | Standard_Real anA; |
428 | if(XCAFDoc_Area::Get(aLabel, anA)) |
429 | di << anA; |
430 | } |
431 | return 0; |
432 | } |
433 | |
434 | |
435 | //======================================================================= |
436 | //function : GetCentroid |
437 | //purpose : |
438 | //======================================================================= |
439 | |
440 | static Standard_Integer GetCentroid (Draw_Interpretor& di, Standard_Integer argc, const char** argv) |
441 | { |
442 | if (argc!=3) { |
443 | di<<"Use: "<<argv[0]<<" DocName {Shape|Label} "<<"\n"; |
444 | return 1; |
445 | } |
446 | Handle(TDocStd_Document) Doc; |
447 | DDocStd::GetDocument(argv[1], Doc); |
448 | if ( Doc.IsNull() ) { di << argv[1] << " is not a document" << "\n"; return 1; } |
449 | |
450 | gp_Pnt aPoint; |
451 | |
452 | TDF_Label aLabel; |
453 | TDF_Tool::Label(Doc->GetData(), argv[2], aLabel); |
454 | if ( aLabel.IsNull() ) { |
455 | TopoDS_Shape aShape= DBRep::Get(argv[2]); |
456 | if ( !aShape.IsNull() ) { |
457 | Handle(XCAFDoc_ShapeTool) STool = XCAFDoc_DocumentTool::ShapeTool(Doc->Main()); |
458 | aLabel = STool->FindShape(aShape); |
459 | } |
460 | } |
461 | if ( !aLabel.IsNull() ) { |
462 | Handle(XCAFDoc_Centroid) aCentroid = new (XCAFDoc_Centroid); |
463 | if (aLabel.FindAttribute (XCAFDoc_Centroid::GetID(), aCentroid)) { |
464 | // aPoint = aCentroid->Get(); |
465 | // di << aPoint.X()<<" "<<aPoint.Y()<<" "<<aPoint.Z(); |
466 | // another case |
467 | if(XCAFDoc_Centroid::Get(aLabel, aPoint)) |
468 | di << aPoint.X()<<" "<<aPoint.Y()<<" "<<aPoint.Z(); |
469 | } |
470 | } |
471 | return 0; |
472 | } |
473 | |
474 | |
475 | //======================================================================= |
476 | //function : doround |
477 | //purpose : auxilary |
478 | //======================================================================= |
479 | |
480 | static inline Standard_Real doround (Standard_Real val, Standard_Real low) |
481 | { |
482 | return Abs ( val ) < low ? 0. : val; |
483 | } |
484 | |
485 | |
486 | //======================================================================= |
487 | //function : CheckProps |
488 | //purpose : |
489 | //======================================================================= |
490 | |
491 | static Standard_Integer CheckProps (Draw_Interpretor& di, Standard_Integer argc, const char** argv) |
492 | { |
493 | if (argc <2) { |
494 | di << "Use: "<<argv[0]<<" DocName [ 0|deflection [Shape|Label] ]"<<"\n"; |
495 | di << " If second argument is 0, standard CADCADE tool is used for" << "\n"; |
496 | di << " computation of volume and CG." << "\n"; |
497 | di << " If second argument is not 0, it is treated as deflection" << "\n"; |
498 | di << " and computation is done by triangulations" << "\n"; |
499 | di << " If the second argument is negative, meshing is forced" << "\n"; |
500 | return 1; |
501 | } |
502 | Handle(TDocStd_Document) Doc; |
503 | DDocStd::GetDocument(argv[1], Doc); |
504 | if ( Doc.IsNull() ) { di << argv[1] << " is not a document" << "\n"; return 1; } |
505 | Standard_Boolean withVolFix = Standard_False; |
506 | if ( argc >2 && atof(argv[2]) != 0 ) withVolFix = Standard_True; |
507 | Standard_Boolean wholeDoc = ( argc <4 ); |
508 | TDF_LabelSequence seq; |
509 | if ( ! wholeDoc ) { |
510 | TDF_Label aLabel; |
511 | TDF_Tool::Label(Doc->GetData(), argv[3], aLabel); |
512 | TopoDS_Shape aShape; |
513 | if ( aLabel.IsNull() ) { |
514 | aShape= DBRep::Get(argv[3]); |
515 | if ( !aShape.IsNull() ) { |
516 | Handle(XCAFDoc_ShapeTool) STool = XCAFDoc_DocumentTool::ShapeTool(Doc->Main()); |
517 | aLabel = STool->FindShape(aShape); |
518 | } |
519 | } |
520 | if ( aLabel.IsNull() ) return 1; |
521 | seq.Append ( aLabel ); |
522 | } |
523 | else { |
524 | Handle(XCAFDoc_ShapeTool) STool = XCAFDoc_DocumentTool::ShapeTool(Doc->Main()); |
525 | STool->GetShapes(seq); |
526 | } |
527 | if ( wholeDoc ) { |
528 | di << "Label Area defect Volume defect dX dY dZ Name" << "\n"; |
529 | } |
530 | for ( Standard_Integer i=1; i <= seq.Length(); i++ ) { |
531 | TDF_Label aLabel = seq(i); |
532 | |
533 | // add instance labels to sequence to process them as well |
534 | if ( XCAFDoc_ShapeTool::IsAssembly ( aLabel ) ) { |
535 | TDF_LabelSequence comp; |
536 | XCAFDoc_ShapeTool::GetComponents ( aLabel, comp ); |
537 | Standard_Integer m=i; |
538 | for ( Standard_Integer k=1; k <= comp.Length(); k++ ) { |
539 | TDF_Label lab = comp(k); |
540 | Handle(XCAFDoc_Volume) aVolume; |
541 | Handle(XCAFDoc_Area) aArea; |
542 | Handle(XCAFDoc_Centroid) aCentroid; |
543 | if ( ! lab.FindAttribute (XCAFDoc_Volume::GetID(), aVolume) && |
544 | ! lab.FindAttribute (XCAFDoc_Area::GetID(), aArea) && |
545 | ! lab.FindAttribute (XCAFDoc_Centroid::GetID(), aCentroid) ) continue; |
546 | seq.InsertAfter ( m++, lab ); |
547 | } |
548 | } |
549 | |
550 | TCollection_AsciiString str; |
551 | TDF_Tool::Entry ( aLabel, str ); |
552 | //printf ( "%s%-12.12s", ( wholeDoc ? "" : "Label " ), str.ToCString() ); |
553 | //fflush ( stdout ); |
554 | char string1[260]; |
555 | sprintf (string1, "%s%-12.12s", ( wholeDoc ? "" : "Label " ), str.ToCString() ); |
556 | di << string1; |
557 | Handle(TDataStd_Name) N; |
558 | if ( aLabel.FindAttribute ( TDataStd_Name::GetID(), N ) && ! wholeDoc ) { |
559 | TCollection_AsciiString name(N->Get(), '?'); |
560 | di << " \"" << name.ToCString() << "\""; |
561 | } |
562 | if ( ! wholeDoc ) di << "\n"; |
563 | |
564 | Handle(XCAFDoc_Volume) aVolume; |
565 | Handle(XCAFDoc_Area) aArea; |
566 | Handle(XCAFDoc_Centroid) aCentroid; |
567 | aLabel.FindAttribute (XCAFDoc_Volume::GetID(), aVolume); |
568 | aLabel.FindAttribute (XCAFDoc_Area::GetID(), aArea); |
569 | aLabel.FindAttribute (XCAFDoc_Centroid::GetID(), aCentroid); |
570 | GProp_GProps G; |
571 | |
572 | TopoDS_Shape aShape = XCAFDoc_ShapeTool::GetShape ( aLabel ); |
573 | if ( ! aArea.IsNull() ) { |
574 | try { |
575 | OCC_CATCH_SIGNALS |
576 | BRepGProp::SurfaceProperties(aShape,G,0.001); |
577 | //printf ("%s%9.1f (%3d%%)%s", ( wholeDoc ? "" : " Area defect: " ), |
578 | // aArea->Get() - G.Mass(), |
579 | // (Standard_Integer)( Abs ( G.Mass() ) > 1e-10 ? 100. * ( aArea->Get() - G.Mass() ) / G.Mass() : 999. ), |
580 | // ( wholeDoc ? "" : "\n" )); |
581 | char string2[260]; |
582 | sprintf (string2, "%s%9.1f (%3d%%)%s", ( wholeDoc ? "" : " Area defect: " ), |
583 | aArea->Get() - G.Mass(), |
584 | (Standard_Integer)( Abs ( G.Mass() ) > 1e-10 ? 100. * ( aArea->Get() - G.Mass() ) / G.Mass() : 999. ), |
585 | ( wholeDoc ? "" : "\n" )); |
586 | di << string2; |
587 | } |
588 | catch (Standard_Failure) { |
589 | //printf ( "%-16.16s", "exception" ); |
590 | char string3[260]; |
591 | sprintf (string3, "%-16.16s", "exception" ); |
592 | di << string3; |
593 | } |
594 | } |
595 | else if ( wholeDoc ) { |
596 | //printf ( "%16.16s", "" ); |
597 | char string4[260]; |
598 | sprintf (string4, "%16.16s", "" ); |
599 | di << string4; |
600 | } |
601 | |
602 | if ( ! aVolume.IsNull() || ! aCentroid.IsNull() ) { |
603 | try { |
604 | OCC_CATCH_SIGNALS |
605 | // Added for check Volume. PTV 08 Nov 2000. |
606 | Standard_Real localVolume; |
607 | gp_Pnt pcg(0,0,0); |
608 | if ( withVolFix ) { |
609 | Standard_Real tol = atof(argv[2]); |
610 | Standard_Boolean withForce = Standard_False; |
611 | if ( tol < 0 ) { |
612 | withForce = Standard_True; |
613 | tol = -tol; |
614 | } |
615 | localVolume = CalculVolume(aShape, pcg, tol, withForce, di); |
616 | } |
617 | else { |
618 | BRepGProp::VolumeProperties(aShape,G,0.001,Standard_True); |
619 | localVolume = G.Mass(); |
620 | pcg = G.CentreOfMass(); |
621 | } |
622 | |
623 | if ( ! aVolume.IsNull() ) { |
624 | //printf ("%s%9.1f (%3d%%)%s", ( wholeDoc ? "" : " Volume defect: " ), |
625 | // aVolume->Get() - localVolume, |
626 | // (Standard_Integer)( Abs ( localVolume ) > 1e-10 ? 100. * ( aVolume->Get() - localVolume ) / localVolume : 999. ), |
627 | // ( wholeDoc ? "" : "\n" )); |
628 | char string5[260]; |
629 | sprintf (string5, "%s%9.1f (%3d%%)%s", ( wholeDoc ? "" : " Volume defect: " ), |
630 | aVolume->Get() - localVolume, |
631 | (Standard_Integer)( Abs ( localVolume ) > 1e-10 ? 100. * ( aVolume->Get() - localVolume ) / localVolume : 999. ), |
632 | ( wholeDoc ? "" : "\n" )); |
633 | di << string5; |
634 | } |
635 | else if ( wholeDoc ) { |
636 | //printf ( "%16.16s", "" ); |
637 | char string6[260]; |
638 | sprintf (string6, "%16.16s", "" ); |
639 | di << string6; |
640 | } |
641 | |
642 | if ( ! aCentroid.IsNull() ) { |
643 | gp_Pnt p = aCentroid->Get(); |
644 | char string7[260]; |
645 | if ( wholeDoc ) { |
646 | //printf ( " %7.2f %7.2f %7.2f", |
647 | // p.X() - pcg.X(), p.Y() - pcg.Y(), p.Z() - pcg.Z() ); |
648 | sprintf (string7, " %7.2f %7.2f %7.2f", |
649 | p.X() - pcg.X(), p.Y() - pcg.Y(), p.Z() - pcg.Z() ); |
650 | } else { |
651 | //printf ( " CG defect: dX=%.3f, dY=%.3f, dZ=%.3f\n", |
652 | // p.X() - pcg.X(), p.Y() - pcg.Y(), p.Z() - pcg.Z() ); |
653 | sprintf (string7, " CG defect: dX=%.3f, dY=%.3f, dZ=%.3f\n", |
654 | p.X() - pcg.X(), p.Y() - pcg.Y(), p.Z() - pcg.Z() ); |
655 | } |
656 | di << string7; |
657 | } |
658 | else if ( wholeDoc ) { |
659 | //printf ( "%24.24s", "" ); |
660 | char string8[260]; |
661 | sprintf (string8, "%24.24s", "" ); |
662 | di << string8; |
663 | } |
664 | } |
665 | catch (Standard_Failure) { |
666 | //printf ( "%40.40s", "exception" ); |
667 | char string9[260]; |
668 | sprintf (string9, "%40.40s", "exception" ); |
669 | di << string9; |
670 | #ifdef DEB |
671 | //fflush ( stdout ); |
672 | di << ": "; |
673 | di << Standard_Failure::Caught()->GetMessageString(); |
674 | di<<" ** Skip"<<"\n"; |
675 | #endif |
676 | } |
677 | } |
678 | else if ( wholeDoc ) { |
679 | //printf ( "%40.40s", "" ); |
680 | char string10[260]; |
681 | sprintf (string10, "%40.40s", "" ); |
682 | di << string10; |
683 | } |
684 | //fflush ( stdout ); |
685 | |
686 | if ( wholeDoc ) { |
687 | if ( ! N.IsNull() ) { |
688 | TCollection_AsciiString name(N->Get(),'?'); |
689 | di << " \"" << name.ToCString() << "\""; |
690 | } |
691 | di << "\n"; |
692 | } |
693 | } |
694 | return 0; |
695 | } |
696 | |
697 | |
698 | //======================================================================= |
699 | //function : ShapeVolume |
700 | //purpose : |
701 | //======================================================================= |
702 | |
703 | static Standard_Integer ShapeVolume (Draw_Interpretor& di, Standard_Integer argc, const char** argv) |
704 | { |
705 | if (argc!=3) { |
706 | di<<"Use: "<<argv[0]<<" Shape deflection "<<"\n"; |
707 | return 1; |
708 | } |
709 | TopoDS_Shape aShape = DBRep::Get(argv[1]); |
710 | if (aShape.IsNull()) return 1; |
711 | gp_Pnt aPoint(0,0,0); |
712 | Standard_Real localVolume; |
713 | Standard_Real tol = atof(argv[2]); |
714 | Standard_Boolean withForce = Standard_False; |
715 | if ( tol < 0 ) { |
716 | withForce = Standard_True; |
717 | tol = -tol; |
718 | } |
719 | localVolume = CalculVolume(aShape, aPoint, tol, withForce, di); |
720 | //cout << "Volume : " << setw(15) << localVolume << "\n" << endl; |
721 | Standard_SStream aSStream; |
722 | aSStream << "Volume : " << setw(15) << localVolume << "\n"; |
723 | di << aSStream; |
724 | return 0; |
725 | } |
726 | |
727 | |
728 | //======================================================================= |
729 | //function : GetMassProps |
730 | //purpose : auxilary for ShapeMassProps |
731 | //======================================================================= |
732 | |
733 | static Standard_Boolean GetMassProps(const TDF_Label& aLabel, gp_XYZ& theCenterGravity, |
734 | Standard_Real& theMassVal, const Standard_Real thetol) |
735 | { |
736 | Standard_Real aDensity = XCAFDoc_MaterialTool::GetDensityForShape(aLabel); |
737 | |
738 | if(aDensity >0) { |
739 | TopoDS_Shape aShape = XCAFDoc_ShapeTool::GetShape(aLabel); |
740 | GProp_GProps G; |
741 | BRepGProp::VolumeProperties(aShape,G,0.001,Standard_True); |
742 | Standard_Real localVolume = G.Mass(); |
743 | theMassVal = aDensity*localVolume; |
744 | theCenterGravity = G.CentreOfMass().XYZ(); |
745 | return Standard_True; |
746 | } |
747 | |
748 | if(aDensity==0) { |
749 | Handle(TNaming_NamedShape) NS; |
750 | if(aLabel.FindAttribute(TNaming_NamedShape::GetID(),NS)) { |
751 | //S = TNaming_Tool::GetShape(NS); |
752 | TopoDS_Shape aSh = NS->Get(); |
753 | if(aSh.ShapeType()==TopAbs_SOLID) return Standard_False; |
754 | } |
755 | |
756 | //TopoDS_Shape aSh = XCAFDoc_ShapeTool::GetShape(aLabel); |
757 | //if(aSh.ShapeType()==TopAbs_SOLID) return Standard_False; |
758 | |
759 | Handle(TDataStd_TreeNode) Node; |
760 | if( aLabel.FindAttribute(XCAFDoc::ShapeRefGUID(),Node) && Node->HasFather() ) { |
761 | TDF_Label SubL = Node->Father()->Label(); |
762 | if(GetMassProps(SubL,theCenterGravity,theMassVal,thetol)) { |
763 | Handle(XCAFDoc_Location) LocationAttribute; |
764 | if(aLabel.FindAttribute(XCAFDoc_Location::GetID(),LocationAttribute)) { |
765 | gp_XYZ tmp = LocationAttribute->Get().Transformation().TranslationPart(); |
766 | theCenterGravity += tmp; |
767 | } |
768 | return Standard_True; |
769 | } |
770 | else |
771 | return Standard_False; |
772 | } |
773 | else { |
774 | // calculate for components |
775 | TDF_LabelSequence comp; |
776 | XCAFDoc_ShapeTool::GetComponents ( aLabel, comp ); |
777 | if(!comp.Length()) |
778 | return Standard_False; |
779 | |
780 | TColgp_Array1OfXYZ anArrCentres(1,comp.Length()); |
781 | TColStd_Array1OfReal anArrMass(1,comp.Length()); |
782 | anArrMass.Init(0.0); |
783 | Standard_Real aTotalMass =0.0; |
7fd59977 |
784 | Standard_Integer k=1; |
785 | for ( ; k <= comp.Length(); k++ ) { |
786 | TDF_Label lab = comp(k); |
787 | gp_XYZ aCenterGravity(0.0,0.0,0.0); |
788 | Standard_Real aMassVal =0.0; |
789 | if(GetMassProps(lab,aCenterGravity,aMassVal,thetol)) { |
790 | anArrCentres.SetValue(k,aCenterGravity); |
791 | anArrMass.SetValue(k,aMassVal); |
792 | aTotalMass += aMassVal; |
793 | } |
794 | } |
795 | if(aTotalMass>0) { |
796 | Standard_Real x= 0.0, y =0.0, z= 0.0; |
797 | for( k=1; k <= anArrMass.Length(); k++) { |
798 | Standard_Real koef = anArrMass.Value(k)/aTotalMass; |
799 | x+= (anArrCentres.Value(k).X()*koef); |
800 | y+= (anArrCentres.Value(k).Y()*koef); |
801 | z+= (anArrCentres.Value(k).Z()*koef); |
802 | } |
803 | theMassVal = aTotalMass; |
804 | theCenterGravity.SetCoord(x,y,z); |
805 | } |
806 | } |
807 | } |
808 | return Standard_True; |
809 | } |
810 | |
811 | |
812 | //======================================================================= |
813 | //function : ShapeMassProps |
814 | //purpose : |
815 | //======================================================================= |
816 | |
817 | static Standard_Integer ShapeMassProps (Draw_Interpretor& di, Standard_Integer argc, const char** argv) |
818 | { |
819 | |
820 | if (argc <2) { |
821 | di << "Use: "<<argv[0]<<" DocName [deflection [Shape|Label] ]"<<"\n"; |
822 | di << " If second argument is 0, standard CADCADE tool is used for" << "\n"; |
823 | di << " computation of volume and CG." << "\n"; |
824 | di << " If second argument is not 0, it is treated as deflection" << "\n"; |
825 | di << " and computation is done by triangulations" << "\n"; |
826 | di << " If the second argument is negative, meshing is forced" << "\n"; |
827 | return 1; |
828 | } |
829 | Handle(TDocStd_Document) Doc; |
830 | DDocStd::GetDocument(argv[1], Doc); |
831 | Standard_Real atol = Precision::Confusion(); |
832 | if(argc >2) |
833 | atol = atof(argv[2]); |
834 | if ( Doc.IsNull() ) { di << argv[1] << " is not a document" << "\n"; return 1; } |
835 | Standard_Boolean wholeDoc = ( argc <4 ); |
836 | TDF_LabelSequence seq; |
837 | if ( ! wholeDoc ) { |
838 | TDF_Label aLabel; |
839 | TDF_Tool::Label(Doc->GetData(), argv[3], aLabel); |
840 | TopoDS_Shape aShape; |
841 | if ( aLabel.IsNull() ) { |
842 | aShape= DBRep::Get(argv[3]); |
843 | if ( !aShape.IsNull() ) { |
844 | Handle(XCAFDoc_ShapeTool) STool = XCAFDoc_DocumentTool::ShapeTool(Doc->Main()); |
845 | aLabel = STool->FindShape(aShape); |
846 | } |
847 | } |
848 | if ( aLabel.IsNull() ) return 1; |
849 | seq.Append ( aLabel ); |
850 | } |
851 | else { |
852 | Handle(XCAFDoc_ShapeTool) STool = XCAFDoc_DocumentTool::ShapeTool(Doc->Main()); |
853 | STool->GetShapes(seq); |
854 | } |
855 | //if ( wholeDoc ) { |
856 | // di << "Label Area defect Volume defect dX dY dZ Name" << "\n"; |
857 | // } |
858 | gp_XYZ aCenterGravity(0.0,0.0,0.0); |
859 | Standard_Real aMassVal =0.0; |
860 | for ( Standard_Integer i=1; i <= seq.Length(); i++ ) { |
861 | TDF_Label aLabel = seq(i); |
862 | GetMassProps(aLabel,aCenterGravity,aMassVal,atol); |
863 | // if(GetMassProps(aLabel,aCenterGravity,aMassVal,atol)) |
864 | // { |
865 | TCollection_AsciiString str; |
866 | TDF_Tool::Entry ( aLabel, str ); |
867 | if(aMassVal>0) { |
868 | di<<"Shape from label : "<<str.ToCString()<<"\n"; |
869 | di<<"Mass = "<<aMassVal<<"\n"; |
870 | di<<"CenterOfGravity X = "<<aCenterGravity.X()<<",Y = "<<aCenterGravity.Y()<<",Z = "<<aCenterGravity.Z()<<"\n"; |
871 | di<<"\n"; |
872 | } |
873 | else { |
874 | // di<<"For one component density is absent"<<"\n"; |
875 | di<<"Shape from label : "<<str.ToCString()<<" not have a mass"<<"\n"; |
876 | } |
877 | } |
878 | return 0; |
879 | } |
880 | |
881 | |
882 | //======================================================================= |
883 | //function : SetMaterial |
884 | //purpose : |
885 | //======================================================================= |
886 | |
887 | static Standard_Integer SetMaterial (Draw_Interpretor& di, Standard_Integer argc, const char** argv) |
888 | { |
889 | if (argc<5) { |
890 | di<<"Use: "<<argv[0]<<" Doc {Label|Shape} name density(g/cu sm) "<<"\n"; |
891 | return 1; |
892 | } |
893 | Handle(TDocStd_Document) Doc; |
894 | DDocStd::GetDocument(argv[1], Doc); |
895 | if ( Doc.IsNull() ) { di << argv[1] << " is not a document" << "\n"; return 1; } |
896 | |
897 | TDF_Label aLabel; |
898 | TDF_Tool::Label(Doc->GetData(), argv[2], aLabel); |
899 | |
900 | Handle(XCAFDoc_MaterialTool) MatTool = XCAFDoc_DocumentTool::MaterialTool(Doc->Main()); |
901 | |
902 | MatTool->SetMaterial(aLabel, new TCollection_HAsciiString(argv[3]), |
903 | new TCollection_HAsciiString(""), atof(argv[4]), |
904 | new TCollection_HAsciiString("density measure"), |
905 | new TCollection_HAsciiString("POSITIVE_RATIO_MEASURE")); |
906 | |
907 | return 0; |
908 | } |
909 | |
910 | |
911 | //======================================================================= |
912 | //function : InitCommands |
913 | //purpose : |
914 | //======================================================================= |
915 | |
916 | void XDEDRAW_Props::InitCommands(Draw_Interpretor& di) |
917 | { |
918 | |
919 | static Standard_Boolean initactor = Standard_False; |
920 | if (initactor) return; initactor = Standard_True; |
921 | |
922 | Standard_CString g = "XDE property's commands"; |
923 | |
924 | di.Add ("XSetVolume","DocName {Label|Shape} volume \t: Seting volume to shape", |
925 | __FILE__, SetVolume, g); |
926 | |
927 | di.Add ("XGetVolume","DocName {Shape|Label} \t: Getting volume of shape", |
928 | __FILE__, GetVolume, g); |
929 | |
930 | di.Add ("XSetArea","DocName {Label|Shape} area \t: Seting area to shape", |
931 | __FILE__, SetArea, g); |
932 | |
933 | di.Add ("XGetArea","DocName {Shape|Label} \t: Getting area of shape", |
934 | __FILE__, GetArea, g); |
935 | |
936 | di.Add ("XSetCentroid","DocName {Label|Shape} x y z \t: Seting centroid to shape", |
937 | __FILE__, SetCentroid, g); |
938 | |
939 | di.Add ("XGetCentroid","DocName {Shape|Label} \t: Getting centroid of shape ", |
940 | __FILE__, GetCentroid, g); |
941 | |
942 | di.Add ("XSetProps","DocName {Shape|Label} [epsilon = 0.001] \t: Compute properties for shape ", |
943 | __FILE__, SetProps, g); |
944 | |
945 | di.Add ("XCheckProps","DocName [ 0|deflection [Shape|Label] ]\t: Check properties recorded for shape ", |
946 | __FILE__, CheckProps, g); |
947 | di.Add ("XShapeVolume","Shape \t: Calculating volume of shape", |
948 | __FILE__, ShapeVolume, g); |
949 | di.Add ("XShapeMassProps","XShapeMassProps DocName [deflection [Shape|Label] ]\t: Get mass value and center of gravity for shape ", |
950 | __FILE__,ShapeMassProps , g); |
951 | di.Add ("XSetMaterial","Doc {Label|Shape} name density(g/cu sm) \t: Set material to shape given by Label", |
952 | __FILE__, SetMaterial, g); |
953 | |
954 | } |