// File: SWDRAW_ShapeAnalysis.cxx // Created: Tue Mar 9 15:48:00 1999 // Author: data exchange team // // sln 19.11.2001. Bug 2: Correction of output of 'statshape' draw function. #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static Standard_Integer tolerance (Draw_Interpretor& di, Standard_Integer argc, const char** argv) { if (argc < 2) { di<<"myshape : analyses a shape\n" << "myshape [mode] valmin : sub-shapes over valmin\n" <<"myshape [mode] valmin valmax : between valmin and valmax\n" <<"myshape [mode] 0 valmax : below valmax\n" <<" more : all shapes(D) v vertices e edges f faces c combined(faces)"<<"\n"; return (argc < 2 ? 0 : 1 /* Error */); } Standard_CString arg1 = argv[1]; TopoDS_Shape Shape = DBRep::Get(arg1); if (Shape.IsNull()) { di<<"Shape unknown : "<Length(); switch (type) { case TopAbs_VERTEX : di<<"Analysing Vertices gives "; break; case TopAbs_EDGE : di<<"Analysing Edges gives "; break; case TopAbs_FACE : di<<"Analysing Faces gives "; break; case TopAbs_SHELL : di<<"Analysing Shells,Faces+content gives "; break; default : di<<"Analysing all sub-shapes gives "; } if (tol1 == 0) di< 1) di<<" , named tol_1 to tol_"<Value(i)); } } return 0; } static Standard_Integer projface (Draw_Interpretor& di, Standard_Integer argc, const char** argv) { if (argc < 4) { di<<"Give FACE name and X Y [Z]"<<"\n"; return 1 /* Error */; } Standard_CString arg1 = argv[1]; TopoDS_Shape Shape = DBRep::Get(arg1); if (Shape.IsNull()) { di<<"Shape unknown : "< 4) { Z = atof (argv[4]); gp_Pnt P3D (X,Y,Z); di<<" Point 3D X = "<Bounds(uf, ul, vf, vl); if (Precision::IsInfinite(uf)) uf = -1000; if (Precision::IsInfinite(ul)) ul = 1000; if (Precision::IsInfinite(vf)) vf = -1000; if (Precision::IsInfinite(vl)) vl = 1000; Standard_Real du = Abs(ul-uf)/10; Standard_Real dv = Abs(vl-vf)/10; GeomAPI_ProjectPointOnSurf proj(P3D, thesurf, uf-du, ul+du, vf-dv, vl+dv); Standard_Integer sol, nPSurf = proj.NbPoints(); di<<" Found "<Value (U,V); di<<" => reproj X = "<ValueOfUV (P3D,BRep_Tool::Tolerance(F)); suval.Coord(U,V); di<<"** ShapeAnalysis_Surface gives U = "<Value(U,V); di<<" => reproj X = "<Value(U,V); di<<" => proj X = "<FirstParameter(); cl = C->LastParameter(); if (argc >= 7) { cf = atof (argv[2]); cl = atof (argv[3]); i0 = 2; } di<<"Curve 3D "< TopoDS_Iterator (it is the same) for (; it.More(); it.Next()) { TopoDS_Edge Edge = TopoDS::Edge (it.Value()); di<<"Wire "<D0 (fuv.X(),fuv.Y(),fxyz); surface->D0 (luv.X(),luv.Y(),lxyz); df3d = fp.Distance (fxyz); maxp3d = Max (maxp3d,df3d); dl3d = lp.Distance (lxyz); maxp3d = Max (maxp3d,dl3d); if (nbe > 1) duv = finuv.Distance (fuv); maxuv = Max (maxuv, duv); // et les min-max u1 = Min (fuv.X(),luv.X()); u2 = Max (fuv.X(),luv.X()); v1 = Min (fuv.Y(),luv.Y()); v2 = Max (fuv.Y(),luv.Y()); if (nbe == 1) { umin = u1; umax = u2; vmin = v1; vmax = v2; } else { umin = Min(umin,u1); umax = Max(umax,u2); vmin = Min(vmin,v1); vmax = Max(vmax,v2); } // et la classification directe if (nbe == 1) { baseuv = fuv.XY(); totcross = 0; } else { gp_XY buv1 = fuv.XY() - baseuv; gp_XY buv2 = luv.XY() - baseuv; totcross += buv2.Crossed(buv1); } } // Resultats ... if (nbe == 1) { debut = fxyz; debuv = fuv; } else { duv = finuv.Distance (fuv); maxuv = Max (maxuv, duv); dvtx = fin.Distance (fxyz); maxvtx = Max (maxvtx,dvtx); di<<" Fin("< 0) di<<"GProps:Mass Out"<<"\n"; else di<<"GProps:Mass In"<<"\n"; /// return (G.Mass() > 0); BRepTopAdaptor_FClass2d fcl (Face,BRep_Tool::Tolerance(Face)); if (fcl.PerformInfinitePoint () == TopAbs_OUT) di<<"Classifier Infinite : Out"<<"\n"; else di<<"Classifier Infinite : In"<<"\n"; gp_Pnt2d pcl; pcl.SetCoord(umin-difu,vmin-difv); if (fcl.Perform (pcl) == TopAbs_OUT) di<<"Classifier UMin-VMin : Out"<<"\n"; pcl.SetCoord(umin-difu,vmax+difv); if (fcl.Perform (pcl) == TopAbs_OUT) di<<"Classifier UMin-VMax : Out"<<"\n"; pcl.SetCoord(umax+difu,vmin-difv); if (fcl.Perform (pcl) == TopAbs_OUT) di<<"Classifier UMax-VMin : Out"<<"\n"; pcl.SetCoord(umax+difu,vmax+difv); if (fcl.Perform (pcl) == TopAbs_OUT) di<<"Classifier UMax-VMax : Out"<<"\n"; } } if (ShapeAnalysis::IsOuterBound (Face)) di<<"ShapeAnalysis: Outer Bound"<<"\n"; else di<<"ShapeAnalysis: Not Outer Bound"<<"\n"; di<<" Total "< 2) arg2 = argv[2]; if (argc > 3) arg3 = argv[3]; TopoDS_Shape Shape = DBRep::Get(arg1); if (Shape.IsNull()) { di<<"Shape unknown : "< 3) { analyzer.ModifyBigSplineMode()=(strstr("bigspl",arg3)!=NULL); analyzer.ModifyIndirectMode()=(strstr("indsur",arg3)!=NULL); analyzer.ModifyOffestSurfaceMode()=(strstr("ofsur",arg3)!=NULL); analyzer.ModifyTrimmed3dMode()=(strstr("trc3d",arg3)!=NULL); analyzer.ModifyOffsetCurveMode()=(strstr("ofcur",arg3)!=NULL); analyzer.ModifyTrimmed2dMode()=(strstr("trc2d",arg3)!=NULL); } analyzer.Perform(Shape); di<<"Count Item\n----- ----"<<"\n"; nb = analyzer.NbEdges(); if(nb>0) di<0) di<0) di<0) di<0) di<0) di<0) di<0) di<0) di<0) di<0) di<0) di<0) di<0) di<0) di<0) di<0) di< 8192 poles"<<"\n"; nb = analyzer.NbBezierSurf(); if(nb>0) di<0) di<0) di<0) di<0) di<0) di<0) di<0) di<0) di<0) di<Length(); i++) { sprintf(nompart,"%s_bigspl_%d",arg2,i); DBRep::Set (nompart,sec->Value(i)); } } if(analyzer.ModifyIndirectMode()) { sec = analyzer.IndirectSec(); for(Standard_Integer i = 1; i <= sec->Length(); i++) { sprintf(nompart,"%s_indsur_%d",arg2,i); DBRep::Set (nompart,sec->Value(i)); } } if(analyzer.ModifyOffestSurfaceMode()) { sec = analyzer.OffsetSurfaceSec(); for(Standard_Integer i = 1; i <= sec->Length(); i++) { sprintf(nompart,"%s_ofsur_%d",arg2,i); DBRep::Set (nompart,sec->Value(i)); } } if(analyzer.ModifyTrimmed3dMode()) { sec = analyzer.Trimmed3dSec(); for(Standard_Integer i = 1; i <= sec->Length(); i++) { sprintf(nompart,"%s_trc3d_%d",arg2,i); DBRep::Set (nompart,sec->Value(i)); } } if(analyzer.ModifyOffsetCurveMode()) { sec = analyzer.OffsetCurveSec(); for(Standard_Integer i = 1; i <= sec->Length(); i++) { sprintf(nompart,"%s_ofcur_%d",arg2,i); DBRep::Set (nompart,sec->Value(i)); } } if(analyzer.ModifyTrimmed2dMode()) { sec = analyzer.Trimmed2dSec(); for(Standard_Integer i = 1; i <= sec->Length(); i++) { sprintf(nompart,"%s_trc2d_%d",arg2,i); DBRep::Set (nompart,sec->Value(i)); } } return 0; } static Standard_Integer XSHAPE_comptoledge (Draw_Interpretor& di, Standard_Integer argc, const char** argv) { if ( argc <2 ) { di << "Use:\n" "> comptol shape [nbpoints=371] [prefix]\n\n" "Computes real tolerance of edges in the shape \n" "as maximal deviation of 3d curve and pcurves.\n" "Deviation is computed by nbpoints sample points (default is 371).\n" "Gives the max, min and average value on all edges in the shape\n" "If prefix is defined, edges with maximal real tolerance and\n" "relation (and corresponding faces) will be saved with such names\n" << "\n"; return 0; } TopoDS_Shape shape = DBRep::Get(argv[1]); if (shape.IsNull()) { di << "Shape name \"" << argv[1] << "\" is invalid" << "\n"; return 1; } Standard_Integer nbpnts = 371; Standard_CString prefix = 0; if ( argc >2 ) { if ( IsDigit(argv[2][0]) ) { nbpnts = atoi(argv[2]); if ( nbpnts <2 ) nbpnts = 2; if ( argc >3 ) prefix = argv[3]; } else prefix = argv[2]; } Standard_Integer num = 0; Standard_Real max=0, min=0, ave=0.; Standard_Real relmax=0, relmin=0, relave=0.; ShapeAnalysis_Edge sae; TopoDS_Edge edmax, edmaxrel; for ( TopExp_Explorer exp(shape,TopAbs_EDGE); exp.More(); exp.Next() ) { Standard_Real tol; TopoDS_Edge edge = TopoDS::Edge(exp.Current()); sae.CheckSameParameter ( edge, tol, nbpnts ); Standard_Real t = BRep_Tool::Tolerance(edge); Standard_Real rel = tol / ( t > Precision::Confusion() ? t : Precision::Confusion() ); ave += tol; relave += rel; if ( ! num ) { max = min = tol; relmax = relmin = rel; edmax = edmaxrel = edge; } else { if ( max < tol ) { max = tol; edmax = edge; } if ( min > tol ) min = tol; if ( relmax < rel ) { relmax = rel; edmaxrel = edge; } if ( relmin > rel ) relmin = rel; } num++; } if ( ! num ) { di << "No edges found in the shape" << "\n"; return 1; } di << "Edges tolerance computed by " << nbpnts << " points: \n" "MAX=" << max << " AVG=" << ave/num << " MIN=" << min << "\n"; di << "Relation real tolerance / tolerance set in edge\n" "MAX=" << relmax << " AVG=" << relave/num << " MIN=" << relmin << "\n"; if ( prefix && prefix[0] ) { char name[21]; sprintf ( name, "%.10s_edge_tol", prefix ); DBRep::Set (name,edmax); di << "Edge with max tolerance saved to " << name; if ( edmax.IsSame ( edmaxrel ) ) di << "\n"; else { sprintf ( name, "%.10s_edge_rel", prefix ); DBRep::Set (name,edmaxrel); di << "; edge with max relation saved to " << name << "\n"; } Standard_Integer num1=0; for ( TopExp_Explorer fac(shape,TopAbs_FACE); fac.More(); fac.Next() ) { TopoDS_Face face = TopoDS::Face ( fac.Current() ); for ( TopExp_Explorer ed(face,TopAbs_EDGE); ed.More(); ed.Next() ) { TopoDS_Edge edge = TopoDS::Edge ( ed.Current() ); if ( edge.IsSame ( edmax ) || edge.IsSame ( edmaxrel ) ) { if ( ! num1 ) di << "Concerned faces saved to shapes "; sprintf ( name, "%.10s_%d", prefix, num1+1 ); DBRep::Set (name,face); //cout << ( num1 ? ", " : "" ) << name; if (num1 == 0) { di << "" << name; } else { di << ", " << name; } num1++; break; } } } if ( num1 >0 ) di << "\n"; } return 0; } //======================================================================= //function : freebounds //purpose : //======================================================================= static Standard_Integer freebounds (Draw_Interpretor& di, Standard_Integer n, const char** a) { if ((n < 3) || (n > 5)) return 1; TopoDS_Shape shape = DBRep::Get(a[1]); if (shape.IsNull()) return 1; Standard_Real toler = atof (a[2]); Standard_Boolean splitclosed = Standard_False, splitopen = Standard_False; if ( n > 3) splitclosed = atoi (a[3]); if ( n > 4) splitopen = atoi (a[4]); ShapeAnalysis_FreeBounds F; if (toler <= 0) F = ShapeAnalysis_FreeBounds (shape, splitclosed, splitopen); else F = ShapeAnalysis_FreeBounds (shape, toler, splitclosed, splitopen); char name[100]; TopoDS_Shape wires = F.GetClosedWires(); sprintf (name, "%s_c", a[1]); DBRep::Set (name, wires); di << name << " - closed wires" << "\n"; wires = F.GetOpenWires(); sprintf (name, "%s_o", a[1]); DBRep::Set (name, wires); di << name << " - open wires" << "\n"; return 0; } //======================================================================= //function : PrintProps //purpose : auxilary for FreeBoundsProps //======================================================================= static void PrintProps(Standard_Integer i, const Handle(ShapeAnalysis_FreeBoundData)& fbd, Draw_Interpretor& di) { char str[100]; Standard_Real area = fbd->Area(); Standard_Real perimeter = fbd->Perimeter(); Standard_Real ratio = fbd->Ratio(); Standard_Real width = fbd->Width(); Standard_Integer notch = fbd->NbNotches(); sprintf(str," %d\t%12.5f\t%12.5f\t%12.5f\t%12.5f\t%d", i, area, perimeter, ratio, width, notch); di< 5) ) { di<<"Usage : freeprops shapename [tolerance [splitclosed [splitopen]]]"<<"\n"; return 1; } TopoDS_Shape source = DBRep::Get(a[1]); if (source.IsNull()) { di<<"Error : unknown shape "< 2) toler = atof(a[2]); if (n > 3) splitclosed = atoi(a[3]); if (n > 4) splitopen = atoi(a[4]); ShapeAnalysis_FreeBoundsProperties analyzer; if (toler > 0) analyzer.Init(source, toler, splitclosed, splitopen); else analyzer.Init(source, splitclosed, splitopen); analyzer.Perform(); TopoDS_Compound closed, open; BRep_Builder B; Standard_Integer nb = analyzer.NbClosedFreeBounds(); di<<"\n"; di<<" \t"<<"Area mm2"<<"\t"<<"Length mm"<<"\t"<<"Ratio L/W"<<"\t"<<"Width mm"<<"\t"<<"Nb noth"<<"\n"; B.MakeCompound(closed); if (nb) { di<<"Closed bounds properties"<<"\n"; for (Standard_Integer i=1; i <= nb; i++) { Handle(ShapeAnalysis_FreeBoundData) fbd = analyzer.ClosedFreeBound(i); PrintProps(i, fbd, di); B.Add(closed,fbd->FreeBound()); } } nb = analyzer.NbOpenFreeBounds(); B.MakeCompound(open); if (nb) { di<<"Open bounds properties"<<"\n"; for (Standard_Integer i=1; i <= nb; i++) { Handle(ShapeAnalysis_FreeBoundData) fbd = analyzer.OpenFreeBound(i); PrintProps(i, fbd, di); B.Add(open,fbd->FreeBound()); } } char name[100]; sprintf (name, "%s_c",a[1]); di << name << " - closed wires, "; DBRep::Set(name, closed); sprintf (name, "%s_o",a[1]); di << name << " - closed wires " << "\n"; DBRep::Set(name, open); return 0; } //======================================================================= //function : closefreebounds //purpose : //======================================================================= static Standard_Integer closefreebounds (Draw_Interpretor& di, Standard_Integer n, const char** a) { if ((n < 4) || (n > 6)) return 1; TopoDS_Shape shape = DBRep::Get(a[1]); if (shape.IsNull()) return 1; Standard_Real sewtoler = atof (a[2]), closetoler = atof (a[3]); Standard_Boolean splitclosed = Standard_False, splitopen = Standard_False; if ( n > 4) splitclosed = atoi (a[3]); if ( n > 5) splitopen = atoi (a[4]); ShapeFix_FreeBounds F; if (sewtoler <= 0) F = ShapeFix_FreeBounds (shape, closetoler, splitclosed, splitopen); else F = ShapeFix_FreeBounds (shape, sewtoler, closetoler, splitclosed, splitopen); char name[100]; TopoDS_Shape wires = F.GetClosedWires(); sprintf (name, "%s_c", a[1]); DBRep::Set (name, wires); di << name << " - closed wires" << "\n"; wires = F.GetOpenWires(); sprintf (name, "%s_o", a[1]); DBRep::Set (name, wires); di << name << " - open wires" << "\n"; return 0; } //======================================================================= //function : MyVISEDG //purpose : //======================================================================= static Standard_Integer MyVISEDG (Draw_Interpretor& /*di*/, Standard_Integer n, const char** a) { if (n >4) return 1; TopoDS_Shape MaListe = DBRep::Get(a[1]); if (MaListe.IsNull()) return 1; TopoDS_Compound TheList = TopoDS::Compound(MaListe); if (TheList.IsNull()) return 1; Standard_Real toler = 0.001; int create = 0; if ( n >= 3) toler = atof(a[2]); if (n == 4 && !strcmp(a[3],"C")) create = 1; ShapeAnalysis_FreeBounds F(TheList,toler); // // // char name[100]; char num[5]; if (!create) { TopoDS_Compound Wires = F.GetClosedWires(); TopoDS_Iterator S(Wires); Standard_Integer iwire = 0; while (S.More()) { sprintf (num,"%d",iwire); name[0] = 'w'; name[1] = '\0'; strncat(name,num,strlen(num)); name[strlen(name)] = '\0'; DBRep::Set(name,S.Value()); S.Next(); iwire++; } iwire = 0; TopoDS_Compound Edges = F.GetOpenWires(); S.Initialize(Edges); iwire = 0; while (S.More()) { sprintf (num,"%d",iwire); name[0] = 'E'; name[1] = '\0'; strncat(name,num,strlen(num)); name[strlen(name)] = '\0'; DBRep::Set(name,S.Value()); S.Next(); iwire++; } } else { } return 0; } static Standard_Integer getareacontour (Draw_Interpretor& di, Standard_Integer n, const char** a) { if (n < 2) return 1; TopoDS_Shape shape = DBRep::Get(a[1]); if (shape.IsNull()) { di<<"Shape is not defined"<<"\n"; return 1; } if(shape.ShapeType() != TopAbs_WIRE) { di<<"invalid type of argument"<<"\n"; return 1; } //Handle(ShapeExtend_WireData) asewd = new ShapeExtend_WireData(TopoDS::Wire(shape)); Standard_Real anArea = ShapeAnalysis::ContourArea(TopoDS::Wire(shape)); di<<"Area = "<