// Created on: 2000-01-20 // Created by: data exchange team // Copyright (c) 2000-2014 OPEN CASCADE SAS // // This file is part of Open CASCADE Technology software library. // // This library is free software; you can redistribute it and/or modify it under // the terms of the GNU Lesser General Public License version 2.1 as published // by the Free Software Foundation, with special exception defined in the file // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT // distribution for complete text of the license and disclaimer of any warranty. // // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. #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 // PLANTAGE IsOuterBound, 15-SEP-1998 //static Standard_Integer numpb = 0; //======================================================================= //function : AdjustByPeriod //purpose : //======================================================================= Standard_Real ShapeAnalysis::AdjustByPeriod(const Standard_Real Val, const Standard_Real ToVal, const Standard_Real Period) { Standard_Real diff = Val - ToVal; Standard_Real D = Abs ( diff ); Standard_Real P = Abs ( Period ); if ( D <= 0.5 * P ) return 0.; if ( P < 1e-100 ) return diff; return ( diff >0 ? -P : P ) * floor( D / P + 0.5 ); } //======================================================================= //function : AdjustToPeriod //purpose : //======================================================================= Standard_Real ShapeAnalysis::AdjustToPeriod(const Standard_Real Val, const Standard_Real ValMin, const Standard_Real ValMax) { return AdjustByPeriod ( Val, 0.5 * ( ValMin + ValMax ), ValMax - ValMin ); } //======================================================================= //function : FindBounds //purpose : //======================================================================= void ShapeAnalysis::FindBounds(const TopoDS_Shape& shape,TopoDS_Vertex& V1,TopoDS_Vertex& V2) { V1.Nullify(); V2.Nullify(); ShapeAnalysis_Edge EA; if (shape.ShapeType() == TopAbs_WIRE) { TopoDS_Wire W = TopoDS::Wire(shape); //invalid work with reversed wires replaced on TopExp TopExp::Vertices(W,V1,V2); //invalid work with reversed wires /*TopoDS_Iterator iterWire(W); //szv#4:S4163:12Mar99 optimized if (iterWire.More()) { TopoDS_Edge E = TopoDS::Edge (iterWire.Value()); V1 = EA.FirstVertex (E); iterWire.Next(); for ( ; iterWire.More(); iterWire.Next() ) E = TopoDS::Edge (iterWire.Value()); V2 = EA.LastVertex (E); }*/ } else if (shape.ShapeType() == TopAbs_EDGE) { V1 = EA.FirstVertex (TopoDS::Edge (shape)); V2 = EA.LastVertex (TopoDS::Edge (shape)); } else if (shape.ShapeType() == TopAbs_VERTEX) V1 = V2 = TopoDS::Vertex (shape); } //======================================================================= //function : ReverceSeq //purpose : auxiliary //======================================================================= template static inline void ReverseSeq (HSequence& Seq) { Standard_Integer j=Seq.Length(); for(Standard_Integer i=1; i=j) break; Seq.Exchange(i,j); j--; } } //======================================================================= //function : TotCross2D //purpose : //======================================================================= Standard_Real ShapeAnalysis::TotCross2D(const Handle(ShapeExtend_WireData)& sewd, const TopoDS_Face& aFace) { Standard_Integer i, nbc = 0; gp_Pnt2d fuv,luv, uv0; Standard_Real totcross=0; for(i=1; i<=sewd->NbEdges(); i++) { TopoDS_Edge edge = sewd->Edge(i); Standard_Real f2d, l2d; Handle(Geom2d_Curve) c2d = BRep_Tool::CurveOnSurface(edge,aFace,f2d,l2d); if ( !c2d.IsNull() ) { nbc++; TColgp_SequenceOfPnt2d SeqPnt; ShapeAnalysis_Curve::GetSamplePoints (c2d, f2d, l2d, SeqPnt); if( edge.Orientation()==1 ) ReverseSeq(SeqPnt); if(nbc==1) { fuv=SeqPnt.Value(1); uv0=fuv; } Standard_Integer j=1; for( ; j<=SeqPnt.Length(); j++) { luv = SeqPnt.Value(j); totcross += (fuv.X()-luv.X())*(fuv.Y()+luv.Y())/2; fuv=luv; } } } totcross += (fuv.X()-uv0.X())*(fuv.Y()+uv0.Y())/2; return totcross; } //======================================================================= //function : ContourArea //purpose : //======================================================================= Standard_Real ShapeAnalysis::ContourArea(const TopoDS_Wire& theWire) //const Handle(ShapeExtend_WireData)& sewd) { Standard_Integer nbc = 0; gp_Pnt fuv,luv, uv0; //Standard_Real totcross=0; gp_XYZ aTotal(0.,0.,0.); TopoDS_Iterator aIte(theWire,Standard_False); //for(i=1; i<=sewd->NbEdges(); i++) { for( ; aIte.More(); aIte.Next()) { TopoDS_Edge edge = TopoDS::Edge(aIte.Value()); //sewd->Edge(i); Standard_Real first, last; Handle(Geom_Curve) c3d = BRep_Tool::Curve(edge,first, last); if ( !c3d.IsNull() ) { TColgp_SequenceOfPnt aSeqPnt; if(!ShapeAnalysis_Curve::GetSamplePoints (c3d, first, last, aSeqPnt)) continue; nbc++; if( edge.Orientation()==TopAbs_REVERSED ) ReverseSeq(aSeqPnt); if(nbc==1) { fuv=aSeqPnt.Value(1); uv0=fuv; } Standard_Integer j=1; for( ; j<=aSeqPnt.Length(); j++) { luv = aSeqPnt.Value(j); aTotal += luv.XYZ()^ fuv.XYZ();// fuv=luv; } } } aTotal += uv0.XYZ()^fuv.XYZ();// Standard_Real anArea = aTotal.Modulus()*0.5; return anArea; } //======================================================================= //function : IsOuterBound //purpose : //======================================================================= Standard_Boolean ShapeAnalysis::IsOuterBound(const TopoDS_Face& face) { TopoDS_Face F = face; TopoDS_Wire W; F.Orientation(TopAbs_FORWARD); Standard_Integer nbw = 0; for (TopExp_Explorer exp(F,TopAbs_WIRE); exp.More(); exp.Next()) { W = TopoDS::Wire (exp.Current()); nbw ++; } //skl 08.04.2002 if (nbw == 1) { Handle(ShapeExtend_WireData) sewd = new ShapeExtend_WireData(W); Standard_Real totcross = TotCross2D(sewd,F); return (totcross >= 0); } else { BRepAdaptor_Surface Ads ( F, Standard_False ); Standard_Real tol = BRep_Tool::Tolerance(F); Standard_Real toluv = Min ( Ads.UResolution(tol), Ads.VResolution(tol) ); BRepTopAdaptor_FClass2d fcl (F,toluv); Standard_Boolean rescl = (fcl.PerformInfinitePoint () == TopAbs_OUT); return rescl; } } //======================================================================= //function : OuterBound //purpose : replacement of bad BRepTools::OuterBound(), to be merged // - skips internal vertices in face, if any, without exception // - returns positively oriented wire rather than greater one //======================================================================= TopoDS_Wire ShapeAnalysis::OuterWire(const TopoDS_Face& face) { TopoDS_Face F = face; F.Orientation(TopAbs_FORWARD); BRep_Builder B; TopoDS_Iterator anIt (F, Standard_False); while (anIt.More()) { TopoDS_Shape aWire = anIt.Value(); anIt.Next(); // skip possible internal vertices in face if (aWire.ShapeType() != TopAbs_WIRE) continue; // if current wire is the last one, return it without analysis if (! anIt.More()) return TopoDS::Wire (aWire); TopoDS_Shape aTestFace = F.EmptyCopied(); B.Add (aTestFace, aWire); if (ShapeAnalysis::IsOuterBound (TopoDS::Face (aTestFace))) return TopoDS::Wire (aWire); } return TopoDS_Wire(); } //======================================================================= //function : GetFaceUVBounds //purpose : //======================================================================= void ShapeAnalysis::GetFaceUVBounds (const TopoDS_Face& F, Standard_Real& UMin, Standard_Real& UMax, Standard_Real& VMin, Standard_Real& VMax) { TopoDS_Face FF = F; FF.Orientation(TopAbs_FORWARD); TopExp_Explorer ex(FF,TopAbs_EDGE); if (!ex.More()) { TopLoc_Location L; BRep_Tool::Surface(F,L)->Bounds(UMin,UMax,VMin,VMax); return; } Bnd_Box2d B; ShapeAnalysis_Edge sae; ShapeAnalysis_Curve sac; for (;ex.More();ex.Next()) { TopoDS_Edge edge = TopoDS::Edge(ex.Current()); Handle(Geom2d_Curve) c2d; Standard_Real f, l; if ( ! sae.PCurve ( edge, F, c2d, f, l, Standard_False ) ) continue; sac.FillBndBox ( c2d, f, l, 20, Standard_True, B ); } B.Get(UMin,VMin,UMax,VMax); }