Loading files
// Created on: 1995-09-08
// Created by: Modelistation
// Copyright (c) 1995-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 <DBRep.hxx>
#include <BRepTest.hxx>
#include <BRepExtrema_Poly.hxx>
#include <BRepExtrema_DistShapeShape.hxx>
#include <BRepExtrema_ShapeProximity.hxx>
#include <BRepExtrema_SelfIntersection.hxx>
#include <BRepLib_MakeVertex.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <Draw_ProgressIndicator.hxx>
#include <TopoDS_Builder.hxx>
#include <TopoDS_Compound.hxx>
#include <Draw.hxx>
#include <Message.hxx>
#include <OSD_Timer.hxx>
#include <TCollection_AsciiString.hxx>
#include <Precision.hxx>
#include <cstdio>
//=================================================================================================
static int distance(Draw_Interpretor& di, int n, const char** a)
{
if (n < 3)
{
return 1;
}
const char* name1 = a[1];
const char* name2 = a[2];
TopoDS_Shape S1 = DBRep::Get(name1);
TopoDS_Shape S2 = DBRep::Get(name2);
if (S1.IsNull() || S2.IsNull())
{
return 1;
}
gp_Pnt P1, P2;
double D;
if (!BRepExtrema_Poly::Distance(S1, S2, P1, P2, D))
{
return 1;
}
// std::cout << " distance : " << D << std::endl;
di << " distance : " << D << "\n";
TopoDS_Edge E = BRepLib_MakeEdge(P1, P2);
DBRep::Set("distance", E);
return 0;
}
static int distmini(Draw_Interpretor& di, int n, const char** a)
{
if (n < 4 || n > 6)
{
return 1;
}
const char * ns1 = (a[2]), *ns2 = (a[3]), *ns0 = (a[1]);
TopoDS_Shape S1(DBRep::Get(ns1)), S2(DBRep::Get(ns2));
double aDeflection = Precision::Confusion();
int anIndex = 4;
if (n >= 5 && a[4][0] != '-')
{
aDeflection = Draw::Atof(a[4]);
anIndex++;
}
bool isMultiThread = false;
for (int anI = anIndex; anI < n; anI++)
{
TCollection_AsciiString anArg(a[anI]);
anArg.LowerCase();
if (anArg == "-parallel")
{
isMultiThread = true;
}
else
{
di << "Syntax error at '" << anArg << "'";
return 1;
}
}
occ::handle<Draw_ProgressIndicator> aProgress = new Draw_ProgressIndicator(di, 1);
BRepExtrema_DistShapeShape dst;
dst.LoadS1(S1);
dst.LoadS2(S2);
dst.SetDeflection(aDeflection);
dst.SetMultiThread(isMultiThread);
dst.Perform(aProgress->Start());
if (dst.IsDone())
{
#ifdef OCCT_DEBUG
// dst.Dump(std::cout);
di << "*** Dump of \"BRepExtrema_DistShapeShape\" in DEBUG mode (begin) *****\n";
Standard_SStream aSStream;
dst.Dump(aSStream);
di << aSStream;
di << "*** Dump of \"BRepExtrema_DistShapeShape\" in DEBUG mode (end) *****\n";
#endif
di << "\"distmini\" command returns:\n";
char named[100];
Sprintf(named, "%s%s", ns0, "_val");
char* tempd = named;
Draw::Set(tempd, dst.Value());
di << named << " ";
for (int i1 = 1; i1 <= dst.NbSolution(); i1++)
{
gp_Pnt P1, P2;
P1 = (dst.PointOnShape1(i1));
P2 = (dst.PointOnShape2(i1));
if (dst.Value() <= 1.e-9)
{
TopoDS_Vertex V = BRepLib_MakeVertex(P1);
char namev[100];
if (i1 == 1)
{
Sprintf(namev, "%s", ns0);
}
else
{
Sprintf(namev, "%s%d", ns0, i1);
}
char* tempv = namev;
DBRep::Set(tempv, V);
di << namev << " ";
}
else
{
char name[100];
TopoDS_Edge E = BRepLib_MakeEdge(P1, P2);
if (i1 == 1)
{
Sprintf(name, "%s", ns0);
}
else
{
Sprintf(name, "%s%d", ns0, i1);
}
char* temp = name;
DBRep::Set(temp, E);
di << name << " ";
}
}
di << "\nOutput is complete.\n";
}
else
{
di << "problem: no distance is found\n";
}
return 0;
}
//=================================================================================================
static int ShapeProximity(Draw_Interpretor& theDI, int theNbArgs, const char** theArgs)
{
if (theNbArgs < 3 || theNbArgs > 6)
{
Message::SendFail() << "Usage: " << theArgs[0]
<< " Shape1 Shape2 [-tol <value> | -value] [-profile]";
return 1;
}
TopoDS_Shape aShape1 = DBRep::Get(theArgs[1]);
TopoDS_Shape aShape2 = DBRep::Get(theArgs[2]);
if (aShape1.IsNull() || aShape2.IsNull())
{
Message::SendFail() << "Error: Failed to find specified shapes";
return 1;
}
BRepExtrema_ShapeProximity aTool(0.0);
bool aProfile = false;
bool isTolerance = false;
bool isValue = false;
for (int anArgIdx = 3; anArgIdx < theNbArgs; ++anArgIdx)
{
TCollection_AsciiString aFlag(theArgs[anArgIdx]);
aFlag.LowerCase();
if (aFlag == "-tol")
{
isTolerance = true;
if (++anArgIdx >= theNbArgs)
{
Message::SendFail() << "Error: wrong syntax at argument '" << aFlag;
return 1;
}
const double aTolerance = Draw::Atof(theArgs[anArgIdx]);
if (aTolerance < 0.0)
{
Message::SendFail() << "Error: Tolerance value should be non-negative";
return 1;
}
else
{
aTool.SetTolerance(aTolerance);
}
}
else if (aFlag == "-value")
{
isValue = true;
aTool.SetTolerance(Precision::Infinite());
}
else if (aFlag == "-profile")
{
aProfile = true;
}
}
if (isTolerance && isValue)
{
Message::SendFail() << "Error: Proximity value could not be computed if the tolerance is set";
return 1;
}
double aInitTime = 0.0;
double aWorkTime = 0.0;
OSD_Timer aTimer;
if (aProfile)
{
aTimer.Start();
}
aTool.LoadShape1(aShape1);
aTool.LoadShape2(aShape2);
if (aProfile)
{
aInitTime = aTimer.ElapsedTime();
aTimer.Reset();
aTimer.Start();
}
// Perform shape proximity test
aTool.Perform();
if (aProfile)
{
aWorkTime = aTimer.ElapsedTime();
aTimer.Stop();
}
if (!aTool.IsDone())
{
Message::SendFail() << "Error: Failed to perform proximity test";
return 1;
}
if (aProfile)
{
theDI << "Number of primitives in shape 1: " << aTool.ElementSet1()->Size() << "\n";
theDI << "Number of primitives in shape 2: " << aTool.ElementSet2()->Size() << "\n";
theDI << "Building data structures: " << aInitTime << "\n";
theDI << "Executing proximity test: " << aWorkTime << "\n";
}
if (isValue)
{
theDI << "Proximity value: " << aTool.Proximity() << "\n";
// proximity points
TopoDS_Vertex aProxVtx1 = BRepLib_MakeVertex(aTool.ProximityPoint1());
TopoDS_Vertex aProxVtx2 = BRepLib_MakeVertex(aTool.ProximityPoint2());
DBRep::Set("ProxPnt1", aProxVtx1);
DBRep::Set("ProxPnt2", aProxVtx2);
// proximity points' status
TCollection_AsciiString ProxPntStatus1;
TCollection_AsciiString ProxPntStatus2;
switch (aTool.ProxPntStatus1())
{
case 0:
ProxPntStatus1 = "Border";
break;
case 1:
ProxPntStatus1 = "Middle";
break;
default:
ProxPntStatus1 = "Unknown";
}
switch (aTool.ProxPntStatus2())
{
case 0:
ProxPntStatus2 = "Border";
break;
case 1:
ProxPntStatus2 = "Middle";
break;
default:
ProxPntStatus2 = "Unknown";
}
theDI << " Status of ProxPnt1 on " << theArgs[1] << " : " << ProxPntStatus1 << "\n";
theDI << " Status of ProxPnt2 on " << theArgs[2] << " : " << ProxPntStatus2 << "\n";
}
else
{
TopoDS_Builder aCompBuilder;
TopoDS_Compound aFaceCompound1;
aCompBuilder.MakeCompound(aFaceCompound1);
for (NCollection_DataMap<int, TColStd_PackedMapOfInteger>::Iterator anIt1(
aTool.OverlapSubShapes1());
anIt1.More();
anIt1.Next())
{
TCollection_AsciiString aStr = TCollection_AsciiString(theArgs[1]) + "_" + (anIt1.Key() + 1);
const TopoDS_Shape& aShape = aTool.GetSubShape1(anIt1.Key());
aCompBuilder.Add(aFaceCompound1, aShape);
DBRep::Set(aStr.ToCString(), aShape);
theDI << aStr << " \n";
}
TopoDS_Compound aFaceCompound2;
aCompBuilder.MakeCompound(aFaceCompound2);
for (NCollection_DataMap<int, TColStd_PackedMapOfInteger>::Iterator anIt2(
aTool.OverlapSubShapes2());
anIt2.More();
anIt2.Next())
{
TCollection_AsciiString aStr = TCollection_AsciiString(theArgs[2]) + "_" + (anIt2.Key() + 1);
const TopoDS_Shape& aShape = aTool.GetSubShape2(anIt2.Key());
aCompBuilder.Add(aFaceCompound2, aShape);
DBRep::Set(aStr.ToCString(), aShape);
theDI << aStr << " \n";
}
DBRep::Set((TCollection_AsciiString(theArgs[1]) + "_" + "overlapped").ToCString(),
aFaceCompound1);
DBRep::Set((TCollection_AsciiString(theArgs[2]) + "_" + "overlapped").ToCString(),
aFaceCompound2);
}
return 0;
}
//=================================================================================================
static int ShapeSelfIntersection(Draw_Interpretor& theDI, int theNbArgs, const char** theArgs)
{
if (theNbArgs < 2 || theNbArgs > 5)
{
Message::SendFail() << "Usage: " << theArgs[0] << " Shape [-tol <value>] [-profile]";
return 1;
}
TopoDS_Shape aShape = DBRep::Get(theArgs[1]);
if (aShape.IsNull())
{
Message::SendFail() << "Error: Failed to find specified shape";
return 1;
}
double aTolerance = 0.0;
bool aToProfile = false;
for (int anArgIdx = 2; anArgIdx < theNbArgs; ++anArgIdx)
{
TCollection_AsciiString aFlag(theArgs[anArgIdx]);
aFlag.LowerCase();
if (aFlag == "-tol")
{
if (++anArgIdx >= theNbArgs)
{
Message::SendFail() << "Error: wrong syntax at argument '" << aFlag;
return 1;
}
const double aValue = Draw::Atof(theArgs[anArgIdx]);
if (aValue < 0.0)
{
Message::SendFail() << "Error: Tolerance value should be non-negative";
return 1;
}
else
{
aTolerance = aValue;
}
}
if (aFlag == "-profile")
{
aToProfile = true;
}
}
OSD_Timer aTimer;
double aInitTime = 0.0;
double aWorkTime = 0.0;
if (aToProfile)
{
aTimer.Start();
}
BRepExtrema_SelfIntersection aTool(aShape, aTolerance);
if (aToProfile)
{
aInitTime = aTimer.ElapsedTime();
aTimer.Reset();
aTimer.Start();
}
// Perform shape self-intersection test
aTool.Perform();
if (!aTool.IsDone())
{
Message::SendFail() << "Error: Failed to perform proximity test";
return 1;
}
if (aToProfile)
{
aWorkTime = aTimer.ElapsedTime();
aTimer.Stop();
theDI << "Building data structure (BVH): " << aInitTime << "\n";
theDI << "Executing self-intersection test: " << aWorkTime << "\n";
}
// Extract output faces
TopoDS_Builder aCompBuilder;
TopoDS_Compound aFaceCompound;
aCompBuilder.MakeCompound(aFaceCompound);
for (NCollection_DataMap<int, TColStd_PackedMapOfInteger>::Iterator anIt(aTool.OverlapElements());
anIt.More();
anIt.Next())
{
TCollection_AsciiString aStr = TCollection_AsciiString(theArgs[1]) + "_" + (anIt.Key() + 1);
const TopoDS_Face& aFace = aTool.GetSubShape(anIt.Key());
aCompBuilder.Add(aFaceCompound, aFace);
DBRep::Set(aStr.ToCString(), aFace);
theDI << aStr << " \n";
}
theDI << "Compound of overlapped sub-faces: " << theArgs[1] << "_overlapped\n";
DBRep::Set((TCollection_AsciiString(theArgs[1]) + "_" + "overlapped").ToCString(), aFaceCompound);
return 0;
}
//=================================================================================================
void BRepTest::ExtremaCommands(Draw_Interpretor& theCommands)
{
static const char* aGroup = "TOPOLOGY Extrema commands";
static bool isDone = false;
if (isDone)
{
return;
}
isDone = true;
theCommands.Add("dist", "dist Shape1 Shape2", __FILE__, distance, aGroup);
theCommands.Add("distmini",
"distmini name Shape1 Shape2 [deflection] [-parallel]",
"\n\t\t: Searches minimal distance between two shapes."
"\n\t\t: The option is:"
"\n\t\t: -parallel : calculate distance in multithreaded mode" __FILE__,
distmini,
aGroup);
theCommands.Add("proximity",
"proximity Shape1 Shape2 [-tol <value> | -value] [-profile]"
"\n\t\t: Searches for pairs of overlapping faces of the given shapes."
"\n\t\t: The options are:"
"\n\t\t: -tol : non-negative tolerance value used for overlapping"
"\n\t\t: test (for zero tolerance, the strict intersection"
"\n\t\t: test will be performed)"
"\n\t\t: -value : compute the proximity value (minimal value which"
"\n\t\t: shows both shapes fully overlapped)"
"\n\t\t: -profile : outputs execution time for main algorithm stages",
__FILE__,
ShapeProximity,
aGroup);
theCommands.Add("selfintersect",
"selfintersect Shape [-tol <value>] [-profile]"
"\n\t\t: Searches for intersected/overlapped faces in the given shape."
"\n\t\t: The algorithm uses shape tessellation (should be computed in"
"\n\t\t: advance), and provides approximate results. The options are:"
"\n\t\t: -tol : non-negative tolerance value used for overlapping"
"\n\t\t: test (for zero tolerance, the strict intersection"
"\n\t\t: test will be performed)"
"\n\t\t: -profile : outputs execution time for main algorithm stages",
__FILE__,
ShapeSelfIntersection,
aGroup);
}
3d097a032This file is pinned to the selected release. Download the original to open it in your design tool.