1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00

0027457: Modeling - Raise exception if scaled transformation is used for shape location

Implementation of raising exception while using scale and mirror transformation in shape location
TopLoc/TopLoc_Location.hxx
TopoDS/TopoDS_Shape.hxx

Implementation of new tools for removing forbidden locations from shapes:
BRepTools/BRepTools_PurgeLocations.cxx
BRepTools/BRepTools_PurgeLocations.hxx
BRepTools/BRepTools.cxx
BRepTools/BRepTools.hxx

Draw commands for transforming shapes are corrected, new draw commands: purgeloc, checkloc added
BRepTest/BRepTest_BasicCommands.cxx

Fixing unstable test bug xde bug24759
StepToGeom/StepToGeom.cxx

All other C++ commits are modification of algorithms used mainly in import/export operations in order to allows these operations if shape locations contains scale and mirror transformations.

New test for command purgeloc added
tests/bugs/moddata_3/bug27457
tests/bugs/moddata_3/bug27457_1
tests/bugs/moddata_3/bug27457_2

Some test corrected according to modifications.
This commit is contained in:
ifv
2021-04-05 11:15:45 +03:00
committed by bugmaster
parent 91428b468b
commit 9592ae247b
41 changed files with 660 additions and 81 deletions

View File

@@ -65,6 +65,9 @@
#include <TopTools_SequenceOfShape.hxx>
#include <GeomLib_CheckCurveOnSurface.hxx>
#include <errno.h>
#include <BRepTools_TrsfModification.hxx>
#include <BRepTools_Modifier.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
//=======================================================================
@@ -1518,3 +1521,33 @@ void BRepTools::RemoveInternals (TopoDS_Shape& theS,
removeInternals (theS, pMKeep);
}
//=======================================================================
//function : CheckLocations
//purpose :
//=======================================================================
void BRepTools::CheckLocations(const TopoDS_Shape& theS,
TopTools_ListOfShape& theProblemShapes)
{
if (theS.IsNull()) return;
TopTools_IndexedMapOfShape aMapS;
TopExp::MapShapes(theS, aMapS, Standard_False, Standard_False);
Standard_Integer i;
for (i = 1; i <= aMapS.Extent(); ++i)
{
const TopoDS_Shape& anS = aMapS(i);
const TopLoc_Location& aLoc = anS.Location();
const gp_Trsf& aTrsf = aLoc.Transformation();
Standard_Boolean isBadTrsf = aTrsf.IsNegative() ||
(Abs(Abs(aTrsf.ScaleFactor()) - 1.) > TopLoc_Location::ScalePrec());
if (isBadTrsf)
{
theProblemShapes.Append(anS);
}
}
}

View File

@@ -29,6 +29,7 @@
#include <Standard_IStream.hxx>
#include <Standard_CString.hxx>
#include <Message_ProgressRange.hxx>
#include <TopTools_ListOfShape.hxx>
class TopoDS_Face;
class TopoDS_Wire;
@@ -358,9 +359,14 @@ public:
//! removal is not going to break topological connectivity between sub-shapes.
//! The flag <theForce> if set to true disables the connectivity check and clears
//! the given shape from all sub-shapes with internal orientation.
Standard_EXPORT static void RemoveInternals (TopoDS_Shape& theS,
const Standard_Boolean theForce = Standard_False);
Standard_EXPORT static void RemoveInternals(TopoDS_Shape& theS,
const Standard_Boolean theForce = Standard_False);
//! Check all locations of shape according criterium:
//! aTrsf.IsNegative() || (Abs(Abs(aTrsf.ScaleFactor()) - 1.) > TopLoc_Location::ScalePrec())
//! All sub-shapes having such locations are put in list theProblemShapes
Standard_EXPORT static void CheckLocations(const TopoDS_Shape& theS,
TopTools_ListOfShape& theProblemShapes);
protected:

View File

@@ -272,7 +272,7 @@ Standard_Boolean BRepTools_Modifier::Rebuild
RevWires = aNSinfo.myRevWires;
B.MakeFace(TopoDS::Face(result),aNSinfo.mySurface,
aNSinfo.myLoc.Predivided(S.Location()),aNSinfo.myToler);
result.Location(S.Location());
result.Location(S.Location(), Standard_False);
if (aNSinfo.myRevFace)
ResOr = TopAbs_REVERSED;
// set specifics flags of a Face
@@ -288,7 +288,7 @@ Standard_Boolean BRepTools_Modifier::Rebuild
else
{ // create new face with bare triangulation
B.MakeFace(TopoDS::Face(result), aTriangulation);
result.Location(S.Location());
result.Location(S.Location(), Standard_False);
}
rebuild = Standard_True;
}
@@ -313,7 +313,7 @@ Standard_Boolean BRepTools_Modifier::Rebuild
aNCinfo.myLoc.Predivided(S.Location()),aNCinfo.myToler);
No3DCurve = Standard_False;
}
result.Location(S.Location());
result.Location(S.Location(), Standard_False);
// result.Orientation(S.Orientation());
// set specifics flags of an Edge
@@ -332,7 +332,7 @@ Standard_Boolean BRepTools_Modifier::Rebuild
else
{ // create new edge with bare polygon
B.MakeEdge(TopoDS::Edge(result), aPolygon);
result.Location(S.Location());
result.Location(S.Location(), Standard_False);
}
rebuild = Standard_True;
}

View File

@@ -0,0 +1,220 @@
// Copyright (c) 2021 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 <BRepTools_PurgeLocations.hxx>
#include <TopoDS_Iterator.hxx>
#include <NCollection_Vector.hxx>
#include <BRepTools.hxx>
#include <StdFail_NotDone.hxx>
#include <BRepTools_TrsfModification.hxx>
#include <BRepTools_Modifier.hxx>
#include <TopLoc_Datum3D.hxx>
//=======================================================================
//function : BRepTools_PurgeLocations
//purpose :
//=======================================================================
BRepTools_PurgeLocations::BRepTools_PurgeLocations() :
myDone(Standard_False)
{
}
//=======================================================================
//function : Perform
//purpose :
//=======================================================================
Standard_Boolean BRepTools_PurgeLocations::Perform(const TopoDS_Shape& theShape)
{
myShape = theShape;
myMapShapes.Clear();
myLocations.Clear();
myDone = Standard_True;
AddShape(myShape);
//Check locations;
Standard_Integer ind;
NCollection_Vector<Standard_Integer> aBadTrsfInds;
for (ind = 1; ; ++ind)
{
const TopLoc_Location& aLoc = myLocations.Location(ind);
if (aLoc.IsIdentity())
break;
const gp_Trsf& aTrsf = aLoc.Transformation();
Standard_Boolean isBadTrsf = aTrsf.IsNegative() ||
(Abs(Abs(aTrsf.ScaleFactor()) - 1.) > TopLoc_Location::ScalePrec());
if (isBadTrsf)
{
aBadTrsfInds.Append(ind);
}
}
if (aBadTrsfInds.IsEmpty())
{
return myDone;
}
Standard_Integer aNbShapes = myMapShapes.Extent();
myMapNewShapes.Clear();
Standard_Integer inds;
for (inds = 1; inds <= aNbShapes; ++inds)
{
const TopoDS_Shape& anS = myMapShapes(inds);
Standard_Integer aLocInd = myLocations.Index(anS.Location());
if(aLocInd == 0)
{
continue;
}
Standard_Integer il;
for (il = 0; il < aBadTrsfInds.Size(); ++il)
{
if (aBadTrsfInds(il) == aLocInd)
{
TopoDS_Shape aTrS;
Standard_Boolean isDone = PurgeLocation(anS, aTrS);
myDone = myDone && isDone;
myMapNewShapes.Bind(anS, aTrS);
break;
}
}
}
if (myReShape.IsNull())
{
myReShape = new BRepTools_ReShape;
}
else
{
myReShape->Clear();
}
TopTools_DataMapIteratorOfDataMapOfShapeShape anIter(myMapNewShapes);
for (; anIter.More(); anIter.Next())
{
const TopoDS_Shape& anOldS = anIter.Key();
const TopoDS_Shape& aNewS = anIter.Value();
myReShape->Replace(anOldS, aNewS);
}
myShape = myReShape->Apply(myShape);
return myDone;
}
//=======================================================================
//function : PurgeLocation
//purpose :
//=======================================================================
Standard_Boolean BRepTools_PurgeLocations::PurgeLocation(const TopoDS_Shape& theS, TopoDS_Shape& theRes)
{
Standard_Boolean isDone = Standard_True;
TopLoc_Location aRefLoc = theS.Location();
Standard_Boolean isEmpty = aRefLoc.IsIdentity();
if (isEmpty)
{
theRes = theS;
return isDone;
}
TopLoc_Location aNullLoc;
theRes = theS.Located(aNullLoc);
while (!isEmpty)
{
const Handle(TopLoc_Datum3D)& aFD = aRefLoc.FirstDatum();
gp_Trsf aTrsf = aFD->Trsf();
Standard_Integer aFP = aRefLoc.FirstPower();
Standard_Boolean isBad = aTrsf.IsNegative() || (Abs(Abs(aTrsf.ScaleFactor()) - 1.) > TopLoc_Location::ScalePrec());
TopLoc_Location aLoc(aFD);
aLoc = aLoc.Powered(aFP);
aTrsf = aLoc.Transformation();
if (isBad)
{
Handle(BRepTools_TrsfModification) aModification = new BRepTools_TrsfModification(aTrsf);
BRepTools_Modifier aModifier(theRes, aModification);
if (aModifier.IsDone())
{
theRes = aModifier.ModifiedShape(theRes);
}
else
{
isDone = Standard_False;
theRes = theRes.Moved(aLoc);
}
}
else
{
theRes = theRes.Moved(aLoc);
}
aRefLoc = aRefLoc.NextLocation();
isEmpty = aRefLoc.IsIdentity();
}
return isDone;
}
//=======================================================================
//function : AddShape
//purpose :
//=======================================================================
void BRepTools_PurgeLocations::AddShape(const TopoDS_Shape& theS)
{
myMapShapes.Add(theS);
myLocations.Add(theS.Location());
TopoDS_Iterator It(theS, Standard_False, Standard_False);
while (It.More()) {
AddShape(It.Value());
It.Next();
}
}
//=======================================================================
//function : GetResult
//purpose :
//=======================================================================
const TopoDS_Shape& BRepTools_PurgeLocations::GetResult() const
{
return myShape;
}
//=======================================================================
//function : IsDone
//purpose :
//=======================================================================
Standard_Boolean BRepTools_PurgeLocations::IsDone() const
{
return myDone;
}
//=======================================================================
//function : ModifiedShape
//purpose :
//=======================================================================
TopoDS_Shape BRepTools_PurgeLocations::ModifiedShape(const TopoDS_Shape& theInitShape) const
{
TopoDS_Shape aShape = theInitShape;
if (myMapNewShapes.IsBound(theInitShape))
aShape = myMapNewShapes.Find(theInitShape);
return aShape;
}

View File

@@ -0,0 +1,62 @@
// Copyright (c) 2021 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.
#ifndef _BRepTools_PurgeLocations_HeaderFile
#define _BRepTools_PurgeLocations_HeaderFile
#include <Standard.hxx>
#include <Standard_Type.hxx>
#include <Standard_Transient.hxx>
#include <BRepTools_ReShape.hxx>
#include <TopTools_LocationSet.hxx>
class TopoDS_Shape;
class BRepTools_PurgeLocations;
//! Removes location datums, which satisfy conditions:
//! aTrsf.IsNegative() || (Abs(Abs(aTrsf.ScaleFactor()) - 1.) > TopLoc_Location::ScalePrec())
//! from all locations of shape and its subshapes
class BRepTools_PurgeLocations
{
public:
Standard_EXPORT BRepTools_PurgeLocations();
//! Removes all locations correspodingly to criterium from theShape.
Standard_EXPORT Standard_Boolean Perform(const TopoDS_Shape& theShape);
//! Returns shape with removed locations.
Standard_EXPORT const TopoDS_Shape& GetResult() const;
Standard_EXPORT Standard_Boolean IsDone() const;
//! Returns modified shape obtained from initial shape.
TopoDS_Shape ModifiedShape(const TopoDS_Shape& theInitShape) const;
private:
void AddShape(const TopoDS_Shape& theS);
Standard_Boolean PurgeLocation(const TopoDS_Shape& theS, TopoDS_Shape& theRes);
Standard_Boolean myDone;
TopoDS_Shape myShape;
TopTools_IndexedMapOfShape myMapShapes;
TopTools_LocationSet myLocations;
TopTools_DataMapOfShapeShape myMapNewShapes;
Handle(BRepTools_ReShape) myReShape;
};
#endif // _BRepTools_PurgeLocations_HeaderFile

View File

@@ -174,7 +174,7 @@ void BRepTools_ReShape::replace (const TopoDS_Shape& ashape,
if (myConsiderLocation) {
//sln 29.11.01 Bug22: Change location of 'newshape' in accordance with location of 'shape'
newshape.Location(newshape.Location().Multiplied(shape.Location().Inverted()));
newshape.Location(newshape.Location().Multiplied(shape.Location().Inverted()), Standard_False);
TopLoc_Location nullLoc;
shape.Location ( nullLoc );
}
@@ -243,8 +243,8 @@ TopoDS_Shape BRepTools_ReShape::Value (const TopoDS_Shape& ashape) const
if (myConsiderLocation) {
//sln 29.11.01 Bug22: Recalculate location of resulting shape in accordance with
//whether result is from map or not
if(fromMap) res.Location(ashape.Location()*res.Location());
else res.Location(ashape.Location());
if(fromMap) res.Location(ashape.Location()*res.Location(), Standard_False);
else res.Location(ashape.Location(), Standard_False);
}
return res;
@@ -300,7 +300,7 @@ Standard_Integer BRepTools_ReShape::Status(const TopoDS_Shape& ashape,
{
TopLoc_Location aResLoc = (res >0 && !newsh.Location().IsIdentity() ?
aLocSh * newsh.Location() : aLocSh);
newsh.Location(aResLoc);
newsh.Location(aResLoc, Standard_False);
}
return res;
}

View File

@@ -26,3 +26,5 @@ BRepTools_TrsfModification.cxx
BRepTools_TrsfModification.hxx
BRepTools_WireExplorer.cxx
BRepTools_WireExplorer.hxx
BRepTools_PurgeLocations.cxx
BRepTools_PurgeLocations.hxx