1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-10 18:51:21 +03:00
occt/src/ShapeFix/ShapeFix_Shape.cxx
dorlov c479c4f6d8 0023638: Data Exchange - Reading IGES file produced invalid shape
Removed double healing of Iges group entities
Added ShapeBuild_ReShape member to the IGESData_IGESModel class, shapes which are registered in ShapeBuild_ReShape class does not process to healing
2023-03-28 01:00:42 +01:00

350 lines
11 KiB
C++

// Created on: 1999-08-09
// Created by: Galina Kulikova
// 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.
#include <BRep_Builder.hxx>
#include <Message_ProgressScope.hxx>
#include <ShapeBuild_ReShape.hxx>
#include <ShapeFix.hxx>
#include <ShapeFix_Edge.hxx>
#include <ShapeFix_Shape.hxx>
#include <ShapeFix_Shell.hxx>
#include <ShapeFix_Solid.hxx>
#include <ShapeFix_Wire.hxx>
#include <Standard_Type.hxx>
#include <TopAbs_ShapeEnum.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Iterator.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Wire.hxx>
IMPLEMENT_STANDARD_RTTIEXT(ShapeFix_Shape,ShapeFix_Root)
//=======================================================================
//function : ShapeFix_Shape
//purpose :
//=======================================================================
ShapeFix_Shape::ShapeFix_Shape()
{
myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
myFixSolidMode = -1;
myFixShellMode = -1;
myFixFaceMode = -1;
myFixWireMode = -1;
myFixSameParameterMode = -1;
myFixVertexPositionMode =0;
myFixVertexTolMode = -1;
myFixSolid = new ShapeFix_Solid;
}
//=======================================================================
//function : ShapeFix_Shape
//purpose :
//=======================================================================
ShapeFix_Shape::ShapeFix_Shape(const TopoDS_Shape& shape)
{
myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
myFixSolidMode = -1;
myFixShellMode = -1;
myFixFaceMode = -1;
myFixWireMode = -1;
myFixSameParameterMode = -1;
myFixSolid = new ShapeFix_Solid;
myFixVertexPositionMode =0;
myFixVertexTolMode = -1;
Init(shape);
}
//=======================================================================
//function : Init
//purpose :
//=======================================================================
void ShapeFix_Shape::Init(const TopoDS_Shape& shape)
{
myShape = shape;
if ( Context().IsNull() ) {
SetContext ( new ShapeBuild_ReShape );
Context()->ModeConsiderLocation() = Standard_True;
}
myResult = myShape;
}
//=======================================================================
//function : Perform
//purpose :
//=======================================================================
Standard_Boolean ShapeFix_Shape::Perform(const Message_ProgressRange& theProgress)
{
Standard_Integer savFixSmallAreaWireMode = 0;
Standard_Integer savFixVertexTolMode = myFixVertexTolMode;
Handle(ShapeFix_Face) fft = FixFaceTool();
if ( !fft.IsNull() ) {
savFixSmallAreaWireMode = fft->FixSmallAreaWireMode();
if ( savFixSmallAreaWireMode == -1 &&
myShape.ShapeType() == TopAbs_FACE ) {
fft->FixSmallAreaWireMode() = Standard_True;
}
}
myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK );
Standard_Boolean status = Standard_False;
TopAbs_ShapeEnum st;
//gka fix for sharing assembly
TopLoc_Location nullLoc,L;
L = myShape.Location();
TopoDS_Shape aShapeNullLoc = myShape;
const Standard_Boolean aIsRecorded = Context()->IsNewShape(myShape);
aShapeNullLoc.Location(nullLoc);
if(aIsRecorded || myMapFixingShape.Contains(aShapeNullLoc))
{
myShape.Location(L, Standard_False);
myResult = Context()->Apply(myShape);
status = Standard_True;
return status;
}
myMapFixingShape.Add(aShapeNullLoc);
//---------------------------------------
myShape.Location(L, Standard_False);
TopoDS_Shape S = Context()->Apply(myShape);
if (NeedFix(myFixVertexPositionMode))
ShapeFix::FixVertexPosition(S,Precision(),Context());
st = S.ShapeType();
// Open progress indication scope for the following fix stages:
// - Fix on Solid or Shell;
// - Fix same parameterization;
Message_ProgressScope aPS(theProgress, "Fixing stage", 2);
switch ( st ) {
case TopAbs_COMPOUND:
case TopAbs_COMPSOLID: {
TopoDS_Shape shape = myShape;
Standard_Integer savFixSameParameterMode = myFixSameParameterMode;
myFixSameParameterMode = Standard_False;
myFixVertexTolMode = Standard_False;
Standard_Integer aShapesNb = S.NbChildren();
// Open progress indication scope for sub-shape fixing
Message_ProgressScope aPSSubShape(aPS.Next(), "Fixing sub-shape", aShapesNb);
for ( TopoDS_Iterator anIter(S); anIter.More() && aPSSubShape.More(); anIter.Next())
{
myShape = anIter.Value();
if (Perform (aPSSubShape.Next()))
status = Standard_True;
}
if ( !aPSSubShape.More() )
return Standard_False; // aborted execution
myFixSameParameterMode = savFixSameParameterMode;
myFixVertexTolMode = savFixVertexTolMode;
myShape = shape;
break;
}
case TopAbs_SOLID: {
if ( !NeedFix(myFixSolidMode) )
break;
myFixSolid->Init(TopoDS::Solid(S));
myFixSolid->SetContext(Context());
if (myFixSolid->Perform (aPS.Next()))
status = Standard_True;
myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE4 );
break;
}
case TopAbs_SHELL: {
if ( !NeedFix(myFixShellMode) )
break;
Handle(ShapeFix_Shell) sfsh = FixShellTool();
sfsh->Init( TopoDS::Shell(S) );
sfsh->SetContext( Context() );
if (sfsh->Perform (aPS.Next()))
status = Standard_True;
myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE4 );
break;
}
case TopAbs_FACE: {
if ( ! NeedFix ( myFixFaceMode ) ) break;
Handle(ShapeFix_Face) sff = FixFaceTool();
Standard_Boolean savTopoMode = sff->FixWireTool()->ModifyTopologyMode();
sff->FixWireTool()->ModifyTopologyMode() = Standard_True;
sff->Init(TopoDS::Face(S));
sff->SetContext(Context());
if(sff->Perform()) {
status = Standard_True;
}
sff->FixWireTool()->ModifyTopologyMode() = savTopoMode;
myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE3 );
break;
}
case TopAbs_WIRE: {
if ( ! NeedFix ( myFixWireMode ) ) break;
Handle(ShapeFix_Wire) sfw = FixWireTool();
Standard_Boolean savTopoMode = sfw->ModifyTopologyMode();
Standard_Boolean savClosedMode = sfw->ClosedWireMode();
sfw->ModifyTopologyMode() = Standard_True;
if ( ! S.Closed() )
sfw->ClosedWireMode() = Standard_False;
sfw->SetFace(TopoDS_Face());
sfw->Load(TopoDS::Wire(S));
sfw->SetContext(Context());
if(sfw->Perform()) {
status = Standard_True;
Context()->Replace(S,sfw->Wire()); // replace for wire only
}
sfw->ModifyTopologyMode() = savTopoMode;
sfw->ClosedWireMode() = savClosedMode;
myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE2 );
break;
}
case TopAbs_EDGE: {
Handle(ShapeFix_Edge) sfe = FixEdgeTool();
sfe->SetContext(Context());
if(sfe->FixVertexTolerance(TopoDS::Edge(S)))
myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 );
break;
}
case TopAbs_VERTEX:
case TopAbs_SHAPE :
default : break;
}
if (!aPS.More())
return Standard_False; // aborted execution
myResult = Context()->Apply(S);
if ( NeedFix(myFixSameParameterMode) )
{
SameParameter (myResult, Standard_False, aPS.Next());
if (!aPS.More())
return Standard_False; // aborted execution
}
if( NeedFix( myFixVertexTolMode))
{
Standard_Integer nbF = 0;
TopExp_Explorer anExpF(myResult, TopAbs_FACE);
for( ; anExpF.More() && nbF <= 1; anExpF.Next())
nbF++;
if( nbF > 1)
{
//fix for bug 0025455
// for case when vertex belong to the different faces it is necessary to check vertices tolerances
//after all fixes.
//This fix it should be performed for example for case when cutting edge was performed.
Handle(ShapeFix_Edge) sfe = FixEdgeTool();
for (anExpF.ReInit(); anExpF.More(); anExpF.Next())
{
TopoDS_Face aF = TopoDS::Face(anExpF.Current());
TopExp_Explorer anExpE (aF, TopAbs_EDGE);
for ( ; anExpE.More(); anExpE.Next())
sfe->FixVertexTolerance( TopoDS::Edge (anExpE.Current()), aF);
}
}
}
myResult = Context()->Apply(myResult);
if ( !fft.IsNull() )
fft->FixSmallAreaWireMode() = savFixSmallAreaWireMode;
return status;
}
//=======================================================================
//function : SameParameter
//purpose :
//=======================================================================
void ShapeFix_Shape::SameParameter(const TopoDS_Shape& sh,
const Standard_Boolean enforce,
const Message_ProgressRange& theProgress)
{
ShapeFix::SameParameter(sh, enforce, 0.0, theProgress);
}
//=======================================================================
//function : Shape
//purpose :
//=======================================================================
TopoDS_Shape ShapeFix_Shape::Shape() const
{
return myResult;
}
//=======================================================================
//function : SetMsgRegistrator
//purpose :
//=======================================================================
void ShapeFix_Shape::SetMsgRegistrator(const Handle(ShapeExtend_BasicMsgRegistrator)& msgreg)
{
ShapeFix_Root::SetMsgRegistrator ( msgreg );
myFixSolid->SetMsgRegistrator ( msgreg );
}
//=======================================================================
//function : SetPrecision
//purpose :
//=======================================================================
void ShapeFix_Shape::SetPrecision (const Standard_Real preci)
{
ShapeFix_Root::SetPrecision ( preci );
myFixSolid->SetPrecision ( preci );
}
//=======================================================================
//function : SetMinTolerance
//purpose :
//=======================================================================
void ShapeFix_Shape::SetMinTolerance (const Standard_Real mintol)
{
ShapeFix_Root::SetMinTolerance ( mintol );
myFixSolid->SetMinTolerance ( mintol );
}
//=======================================================================
//function : SetMaxTolerance
//purpose :
//=======================================================================
void ShapeFix_Shape::SetMaxTolerance (const Standard_Real maxtol)
{
ShapeFix_Root::SetMaxTolerance ( maxtol );
myFixSolid->SetMaxTolerance ( maxtol );
}
//=======================================================================
//function : Status
//purpose :
//=======================================================================
Standard_Boolean ShapeFix_Shape::Status (const ShapeExtend_Status status) const
{
return ShapeExtend::DecodeStatus ( myStatus, status );
}