185b4d07723d8eefbc8dedc4e1b926c47686a9ae
[occt.git] / src / XDEDRAW / XDEDRAW_Props.cxx
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;
784       Standard_Boolean isFind = Standard_True;
785       Standard_Integer k=1;
786       for ( ; k <= comp.Length(); k++ ) {
787         TDF_Label lab = comp(k);
788         gp_XYZ aCenterGravity(0.0,0.0,0.0);
789         Standard_Real aMassVal =0.0;
790         if(GetMassProps(lab,aCenterGravity,aMassVal,thetol)) {
791           anArrCentres.SetValue(k,aCenterGravity);
792           anArrMass.SetValue(k,aMassVal);
793           aTotalMass += aMassVal;
794         }
795       }
796       if(aTotalMass>0) {
797         Standard_Real x= 0.0, y =0.0, z= 0.0;
798         for( k=1; k <= anArrMass.Length(); k++) {
799           Standard_Real koef = anArrMass.Value(k)/aTotalMass;
800           x+= (anArrCentres.Value(k).X()*koef);
801           y+= (anArrCentres.Value(k).Y()*koef);
802           z+= (anArrCentres.Value(k).Z()*koef);
803         }
804         theMassVal = aTotalMass;
805         theCenterGravity.SetCoord(x,y,z);
806       }
807     }
808   }
809   return Standard_True;
810 }
811
812
813 //=======================================================================
814 //function : ShapeMassProps
815 //purpose  : 
816 //=======================================================================
817
818 static Standard_Integer ShapeMassProps (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
819 {
820   
821   if (argc <2) {
822     di << "Use: "<<argv[0]<<" DocName [deflection [Shape|Label] ]"<<"\n";
823     di << "     If second argument is 0, standard CADCADE tool is used for" << "\n";
824     di << "     computation of volume and CG." << "\n";
825     di << "     If second argument is not 0, it is treated as deflection" << "\n";
826     di << "     and computation is done by triangulations" << "\n";
827     di << "     If the second argument is negative, meshing is forced" << "\n";
828     return 1;
829   }
830   Handle(TDocStd_Document) Doc;
831   DDocStd::GetDocument(argv[1], Doc);
832   Standard_Real atol = Precision::Confusion();
833   if(argc >2)
834     atol  = atof(argv[2]);
835   if ( Doc.IsNull() ) { di << argv[1] << " is not a document" << "\n"; return 1; }
836   Standard_Boolean wholeDoc = ( argc <4 );
837   TDF_LabelSequence seq;
838   if ( ! wholeDoc ) {
839     TDF_Label aLabel;
840     TDF_Tool::Label(Doc->GetData(), argv[3], aLabel);
841     TopoDS_Shape aShape;
842     if ( aLabel.IsNull() ) {
843       aShape= DBRep::Get(argv[3]);
844       if ( !aShape.IsNull() ) {
845         Handle(XCAFDoc_ShapeTool) STool = XCAFDoc_DocumentTool::ShapeTool(Doc->Main());
846         aLabel = STool->FindShape(aShape);
847       }
848     }
849     if ( aLabel.IsNull() ) return 1;
850     seq.Append ( aLabel );
851   }
852   else {
853     Handle(XCAFDoc_ShapeTool) STool = XCAFDoc_DocumentTool::ShapeTool(Doc->Main());
854     STool->GetShapes(seq);
855   }
856   //if ( wholeDoc ) {
857   //  di << "Label            Area defect   Volume defect    dX      dY      dZ    Name" << "\n";
858  // }
859   gp_XYZ aCenterGravity(0.0,0.0,0.0);
860   Standard_Real aMassVal =0.0;
861   for ( Standard_Integer i=1; i <= seq.Length(); i++ ) {
862     TDF_Label aLabel = seq(i);
863     GetMassProps(aLabel,aCenterGravity,aMassVal,atol);
864 //    if(GetMassProps(aLabel,aCenterGravity,aMassVal,atol))
865 //    {
866       TCollection_AsciiString str;
867       TDF_Tool::Entry ( aLabel, str );
868     if(aMassVal>0) {
869       di<<"Shape from label : "<<str.ToCString()<<"\n";
870       di<<"Mass = "<<aMassVal<<"\n";
871       di<<"CenterOfGravity X = "<<aCenterGravity.X()<<",Y = "<<aCenterGravity.Y()<<",Z = "<<aCenterGravity.Z()<<"\n";
872       di<<"\n";
873     }
874     else {
875 //      di<<"For one component density is absent"<<"\n";
876       di<<"Shape from label : "<<str.ToCString()<<" not have a mass"<<"\n";
877     }
878   }
879   return 0;
880 }
881
882
883 //=======================================================================
884 //function : SetMaterial
885 //purpose  : 
886 //=======================================================================
887
888 static Standard_Integer SetMaterial (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
889 {
890   if (argc<5) {
891     di<<"Use: "<<argv[0]<<" Doc {Label|Shape} name density(g/cu sm) "<<"\n";
892     return 1;
893   }
894   Handle(TDocStd_Document) Doc;   
895   DDocStd::GetDocument(argv[1], Doc);
896   if ( Doc.IsNull() ) { di << argv[1] << " is not a document" << "\n"; return 1; }
897   
898   TDF_Label aLabel;
899   TDF_Tool::Label(Doc->GetData(), argv[2], aLabel);
900
901   Handle(XCAFDoc_MaterialTool) MatTool = XCAFDoc_DocumentTool::MaterialTool(Doc->Main());
902
903   MatTool->SetMaterial(aLabel, new TCollection_HAsciiString(argv[3]),
904                        new TCollection_HAsciiString(""), atof(argv[4]),
905                        new TCollection_HAsciiString("density measure"),
906                        new TCollection_HAsciiString("POSITIVE_RATIO_MEASURE"));
907
908   return 0;
909 }
910
911
912 //=======================================================================
913 //function : InitCommands
914 //purpose  : 
915 //=======================================================================
916
917 void XDEDRAW_Props::InitCommands(Draw_Interpretor& di) 
918 {
919
920   static Standard_Boolean initactor = Standard_False;
921   if (initactor) return;  initactor = Standard_True;
922
923   Standard_CString g = "XDE property's commands";
924   
925   di.Add ("XSetVolume","DocName {Label|Shape} volume \t: Seting volume to shape",
926                    __FILE__, SetVolume, g);
927
928   di.Add ("XGetVolume","DocName {Shape|Label} \t: Getting volume of shape",
929                    __FILE__, GetVolume, g);
930
931   di.Add ("XSetArea","DocName {Label|Shape} area \t: Seting area to shape",
932                    __FILE__, SetArea, g);
933
934   di.Add ("XGetArea","DocName {Shape|Label} \t: Getting area of shape",
935                    __FILE__, GetArea, g);
936
937   di.Add ("XSetCentroid","DocName  {Label|Shape} x y z \t: Seting centroid to shape",
938                    __FILE__, SetCentroid, g);
939
940   di.Add ("XGetCentroid","DocName {Shape|Label} \t: Getting centroid of shape ",
941                    __FILE__, GetCentroid, g);
942
943   di.Add ("XSetProps","DocName {Shape|Label} [epsilon = 0.001] \t: Compute properties for shape ",
944                    __FILE__, SetProps, g);
945
946   di.Add ("XCheckProps","DocName [ 0|deflection [Shape|Label] ]\t: Check properties recorded for shape ",
947                    __FILE__, CheckProps, g);
948   di.Add ("XShapeVolume","Shape \t: Calculating volume of shape",
949                    __FILE__, ShapeVolume, g);
950   di.Add ("XShapeMassProps","XShapeMassProps DocName [deflection [Shape|Label] ]\t: Get mass value and center of gravity for shape ",
951                    __FILE__,ShapeMassProps , g);
952   di.Add ("XSetMaterial","Doc {Label|Shape} name density(g/cu sm) \t: Set material to shape given by Label",
953                    __FILE__, SetMaterial, g);
954
955 }