1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-16 10:08:36 +03:00
occt/src/ShapeAnalysis/ShapeAnalysis_ShapeContents.cxx

288 lines
8.8 KiB
C++

// Created on: 1999-02-25
// Created by: Pavel DURANDIN
// Copyright (c) 1999-1999 Matra Datavision
// Copyright (c) 1999-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.
//szv#4 S4163
#include <BRep_Tool.hxx>
#include <Geom2d_Curve.hxx>
#include <Geom2d_OffsetCurve.hxx>
#include <Geom2d_TrimmedCurve.hxx>
#include <Geom_BezierSurface.hxx>
#include <Geom_Curve.hxx>
#include <Geom_ElementarySurface.hxx>
#include <Geom_OffsetCurve.hxx>
#include <Geom_OffsetSurface.hxx>
#include <Geom_RectangularTrimmedSurface.hxx>
#include <Geom_Surface.hxx>
#include <Geom_TrimmedCurve.hxx>
#include <ShapeAnalysis_ShapeContents.hxx>
#include <ShapeAnalysis_Wire.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Shell.hxx>
#include <TopoDS_Solid.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopoDS_Wire.hxx>
#include <TopTools_HSequenceOfShape.hxx>
#include <TopTools_MapOfShape.hxx>
ShapeAnalysis_ShapeContents::ShapeAnalysis_ShapeContents()
{
myBigSplineSec = new TopTools_HSequenceOfShape;
myIndirectSec = new TopTools_HSequenceOfShape;
myOffsetSurfaceSec = new TopTools_HSequenceOfShape;
myTrimmed3dSec = new TopTools_HSequenceOfShape;
myOffsetCurveSec = new TopTools_HSequenceOfShape;
myTrimmed2dSec = new TopTools_HSequenceOfShape;
ClearFlags();
}
void ShapeAnalysis_ShapeContents::Clear()
{
myNbSolids = 0;
myNbShells = 0;
myNbFaces = 0;
myNbWires = 0;
myNbEdges = 0;
myNbVertices = 0;
myNbSolidsWithVoids = 0;
myNbBigSplines = 0;
myNbC0Surfaces = 0;
myNbC0Curves = 0;
myNbOffsetSurf = 0;
myNbIndirectSurf = 0;
myNbOffsetCurves = 0;
myNbTrimmedCurve2d = 0;
myNbTrimmedCurve3d =0;
myNbBSplibeSurf = 0;
myNbBezierSurf = 0;
myNbTrimSurf = 0;
myNbWireWitnSeam = 0;
myNbWireWithSevSeams = 0;
myNbFaceWithSevWires = 0;
myNbNoPCurve = 0;
myNbFreeFaces = 0;
myNbFreeWires = 0;
myNbFreeEdges = 0;
myNbSharedSolids = 0;
myNbSharedShells = 0;
myNbSharedFaces = 0;
myNbSharedWires = 0;
myNbSharedFreeWires = 0;
myNbSharedFreeEdges = 0;
myNbSharedEdges = 0;
myNbSharedVertices = 0;
myBigSplineSec->Clear();
myIndirectSec->Clear();
myOffsetSurfaceSec->Clear();
myTrimmed3dSec->Clear();
myOffsetCurveSec->Clear();
myTrimmed2dSec->Clear();
}
void ShapeAnalysis_ShapeContents::ClearFlags()
{
myBigSplineMode = Standard_False;
myIndirectMode = Standard_False;
myOffsetSurfaceMode = Standard_False;
myTrimmed3dMode = Standard_False;
myOffsetCurveMode = Standard_False;
myTrimmed2dMode = Standard_False;
}
void ShapeAnalysis_ShapeContents::Perform(const TopoDS_Shape& Shape)
{
Clear();
// On y va
TopExp_Explorer exp;
TopTools_MapOfShape mapsh;
// On note pour les SOLIDES : ceux qui ont des trous (plus d un SHELL)
for (exp.Init (Shape,TopAbs_SOLID); exp.More(); exp.Next()) {
TopoDS_Solid sol = TopoDS::Solid (exp.Current());
sol.Location(TopLoc_Location());
mapsh.Add(sol);
Standard_Integer nbs = 0;
for (TopExp_Explorer shel (sol,TopAbs_SHELL); shel.More(); shel.Next())
nbs ++;
if (nbs > 1) myNbSolidsWithVoids++;
myNbSolids++;
}
myNbSharedSolids = mapsh.Extent();
// Pour les SHELLS, on compte les faces dans les SHELLS
// Ensuite une soustraction, et on a les faces libres
mapsh.Clear();
Standard_Integer nbfaceshell = 0;
for (exp.Init (Shape,TopAbs_SHELL); exp.More(); exp.Next()) {
myNbShells++;
TopoDS_Shell she = TopoDS::Shell(exp.Current());
she.Location(TopLoc_Location());
mapsh.Add(she);
for (TopExp_Explorer shel (she,TopAbs_FACE); shel.More(); shel.Next())
nbfaceshell ++;
}
myNbSharedShells = mapsh.Extent();
// On note pour les FACES pas mal de choses (surface, topologie)
// * Surface BSpline > 8192 poles
// * Surface BSpline "OnlyC0" (not yet impl)
// * Surface Offset
// * Surface Elementaire INDIRECTE
// * Presence de COUTURES; en particulier WIRE A PLUS D UNE COUTURE
// * Edge : OffsetCurve
mapsh.Clear();
for (exp.Init (Shape,TopAbs_FACE); exp.More(); exp.Next()) {
TopoDS_Face face = TopoDS::Face(exp.Current());
myNbFaces++;
TopLoc_Location loc;
Handle(Geom_Surface) surf = BRep_Tool::Surface (face,loc);
face.Location(TopLoc_Location());
mapsh.Add(face);
Handle(Geom_RectangularTrimmedSurface) trsu =
Handle(Geom_RectangularTrimmedSurface)::DownCast (surf);
if (!trsu.IsNull()) {
myNbTrimSurf++;
surf = trsu->BasisSurface();
}
//#10 rln 27/02/98 BUC50003 entity 56
//C0 if at least in one direction (U or V)
if (!surf.IsNull() && !(surf->IsCNu(1) && surf->IsCNv(1))) {
myNbC0Surfaces++;
}
Handle(Geom_BSplineSurface) bsps = Handle(Geom_BSplineSurface)::DownCast(surf);
if (!bsps.IsNull()) {
myNbBSplibeSurf++;
if (bsps->NbUPoles() * bsps->NbVPoles() > 8192) {
myNbBigSplines++;
if (myBigSplineMode) myBigSplineSec->Append(face);
}
}
Handle(Geom_ElementarySurface) els = Handle(Geom_ElementarySurface)::DownCast(surf);
if (!els.IsNull()) {
if (!els->Position().Direct()) {
myNbIndirectSurf++;
if (myIndirectMode) myIndirectSec->Append(face);
}
}
if (surf->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
myNbOffsetSurf++;
if (myOffsetSurfaceMode) myOffsetSurfaceSec->Append(face);
}
else if (surf->IsKind(STANDARD_TYPE(Geom_BezierSurface))) {
myNbBezierSurf++;
}
Standard_Integer maxseam = 0, nbwires = 0;
for (TopExp_Explorer wires(face,TopAbs_WIRE); wires.More(); wires.Next()) {
TopoDS_Wire wire = TopoDS::Wire (wires.Current());
Standard_Integer nbseam = 0;
nbwires ++;
for (TopExp_Explorer edg(wire,TopAbs_EDGE); edg.More(); edg.Next()) {
TopoDS_Edge edge = TopoDS::Edge (edg.Current());
Standard_Real first,last;
if (BRep_Tool::IsClosed (edge,face)) nbseam ++;
Handle(Geom_Curve) c3d = BRep_Tool::Curve (edge,first,last);
if (!c3d.IsNull()) {
if (c3d->IsKind (STANDARD_TYPE(Geom_TrimmedCurve))) {
myNbTrimmedCurve3d++;
if (myTrimmed3dMode) myTrimmed3dSec->Append(face);
}
}
Handle(Geom2d_Curve) c2d = BRep_Tool::CurveOnSurface (edge,face,first,last);
if (c2d.IsNull()) myNbNoPCurve++;
else if (c2d->IsKind (STANDARD_TYPE(Geom2d_OffsetCurve))) {
myNbOffsetCurves++;
if (myOffsetCurveMode) myOffsetCurveSec->Append(face);
}
else if (c2d->IsKind (STANDARD_TYPE(Geom2d_TrimmedCurve))) {
myNbTrimmedCurve2d++;
if (myTrimmed2dMode) myTrimmed2dSec->Append(face);
}
}
if (nbseam > maxseam) maxseam = nbseam;
}
if (maxseam == 1) myNbWireWitnSeam++;
else if (maxseam > 1)
myNbWireWithSevSeams++;
if (nbwires > 1) myNbFaceWithSevWires++;
}
myNbSharedFaces = mapsh.Extent();
mapsh.Clear();
for (exp.Init (Shape,TopAbs_WIRE); exp.More(); exp.Next()) {
TopoDS_Wire wire = TopoDS::Wire(exp.Current());
wire.Location(TopLoc_Location());
mapsh.Add(wire);
myNbWires++;
}
myNbSharedWires = mapsh.Extent();
// Ne pas oublier les FACES :
myNbFreeFaces = myNbFaces - nbfaceshell;
mapsh.Clear();
for (exp.Init (Shape,TopAbs_EDGE); exp.More(); exp.Next()) {
TopoDS_Edge edge = TopoDS::Edge (exp.Current());
edge.Location(TopLoc_Location());
mapsh.Add (edge);
TopLoc_Location loc;
Standard_Real first,last;
myNbEdges++;
Handle(Geom_Curve) c3d = BRep_Tool::Curve (edge,loc,first,last);
if (!c3d.IsNull() && c3d->IsKind(STANDARD_TYPE(Geom_OffsetCurve))) {
myNbOffsetCurves++;
if (myOffsetCurveMode) myOffsetCurveSec->Append(edge);
}
if (!c3d.IsNull() && !c3d->IsCN(1)) myNbC0Curves++;
}
myNbSharedEdges=mapsh.Extent();
mapsh.Clear();
for (exp.Init (Shape,TopAbs_VERTEX); exp.More(); exp.Next()) {
TopoDS_Vertex vert = TopoDS::Vertex(exp.Current());
vert.Location(TopLoc_Location());
myNbVertices++;
mapsh.Add (vert);
}
myNbSharedVertices=mapsh.Extent();
mapsh.Clear();
for (exp.Init(Shape, TopAbs_EDGE, TopAbs_FACE); exp.More(); exp.Next()) {
TopoDS_Edge edge = TopoDS::Edge (exp.Current());
edge.Location(TopLoc_Location());
myNbFreeEdges++;
mapsh.Add (edge);
}
myNbSharedFreeEdges=mapsh.Extent();
mapsh.Clear();
for (exp.Init(Shape, TopAbs_WIRE, TopAbs_FACE); exp.More(); exp.Next()) {
TopoDS_Wire wire = TopoDS::Wire(exp.Current());
wire.Location(TopLoc_Location());
myNbFreeWires++;
mapsh.Add (wire);
}
myNbSharedFreeWires=mapsh.Extent();
}