[TD]detail of rotated ComplexSection

This commit is contained in:
wandererfan
2022-12-10 20:08:32 -05:00
committed by WandererFan
parent 02386e3150
commit 100d4956c8
11 changed files with 1541 additions and 1592 deletions

View File

@@ -23,30 +23,30 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <QtConcurrentRun>
# include <sstream>
# include <Bnd_Box.hxx>
# include <BRepAlgoAPI_Common.hxx>
# include <BRepBndLib.hxx>
# include <BRepBuilderAPI_Copy.hxx>
# include <BRepBuilderAPI_MakeFace.hxx>
# include <BRep_Builder.hxx>
# include <BRepPrimAPI_MakeCylinder.hxx>
# include <BRepPrimAPI_MakePrism.hxx>
# include <BRepProj_Projection.hxx>
# include <BRepTools.hxx>
# include <gp_Ax2.hxx>
# include <gp_Dir.hxx>
# include <gp_Pln.hxx>
# include <gp_Pnt.hxx>
# include <TopExp_Explorer.hxx>
# include <TopoDS_Compound.hxx>
# include <TopoDS_Edge.hxx>
# include <TopoDS_Face.hxx>
# include <TopoDS.hxx>
# include <TopoDS_Shape.hxx>
# include <TopoDS_Shell.hxx>
# include <TopoDS_Solid.hxx>
#include <BRepAlgoAPI_Common.hxx>
#include <BRepBndLib.hxx>
#include <BRepBuilderAPI_Copy.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <BRepPrimAPI_MakeCylinder.hxx>
#include <BRepPrimAPI_MakePrism.hxx>
#include <BRepProj_Projection.hxx>
#include <BRepTools.hxx>
#include <BRep_Builder.hxx>
#include <Bnd_Box.hxx>
#include <QtConcurrentRun>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Compound.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Shell.hxx>
#include <TopoDS_Solid.hxx>
#include <gp_Ax2.hxx>
#include <gp_Dir.hxx>
#include <gp_Pln.hxx>
#include <gp_Pnt.hxx>
#include <sstream>
#endif
#include <App/Application.h>
@@ -54,8 +54,9 @@
#include <Base/Console.h>
#include <Base/Parameter.h>
#include "DrawViewDetail.h"
#include "DrawComplexSection.h"
#include "DrawUtil.h"
#include "DrawViewDetail.h"
#include "DrawViewSection.h"
#include "GeometryObject.h"
#include "Preferences.h"
@@ -69,26 +70,25 @@ using namespace TechDraw;
PROPERTY_SOURCE(TechDraw::DrawViewDetail, TechDraw::DrawViewPart)
DrawViewDetail::DrawViewDetail() :
m_waitingForDetail(false),
m_saveDvp(nullptr),
m_saveDvs(nullptr)
DrawViewDetail::DrawViewDetail() : m_waitingForDetail(false), m_saveDvp(nullptr), m_saveDvs(nullptr)
{
static const char *dgroup = "Detail";
static const char* dgroup = "Detail";
ADD_PROPERTY_TYPE(BaseView ,(nullptr), dgroup, App::Prop_None, "2D View source for this Section");
ADD_PROPERTY_TYPE(BaseView, (nullptr), dgroup, App::Prop_None,
"2D View source for this Section");
BaseView.setScope(App::LinkScope::Global);
ADD_PROPERTY_TYPE(AnchorPoint ,(0, 0,0) ,dgroup, App::Prop_None, "Location of detail in BaseView");
ADD_PROPERTY_TYPE(AnchorPoint, (0, 0, 0), dgroup, App::Prop_None,
"Location of detail in BaseView");
ADD_PROPERTY_TYPE(Radius, (10.0), dgroup, App::Prop_None, "Size of detail area");
ADD_PROPERTY_TYPE(Reference ,("1"), dgroup, App::Prop_None, "An identifier for this detail");
ADD_PROPERTY_TYPE(Reference, ("1"), dgroup, App::Prop_None, "An identifier for this detail");
getParameters();
m_fudge = 1.01;
//hide Properties not relevant to DVDetail
Direction.setStatus(App::Property::ReadOnly, true); //Should be same as BaseView
Rotation.setStatus(App::Property::ReadOnly, true); //same as BaseView
ScaleType.setValue("Custom"); //dvd uses scale from BaseView
Direction.setStatus(App::Property::ReadOnly, true);//Should be same as BaseView
Rotation.setStatus(App::Property::ReadOnly, true); //same as BaseView
ScaleType.setValue("Custom"); //dvd uses scale from BaseView
}
DrawViewDetail::~DrawViewDetail()
@@ -106,10 +106,8 @@ short DrawViewDetail::mustExecute() const
TechDraw::DrawView::mustExecute();
}
if (AnchorPoint.isTouched() ||
Radius.isTouched() ||
BaseView.isTouched() ||
Reference.isTouched()) {
if (AnchorPoint.isTouched() || Radius.isTouched() || BaseView.isTouched()
|| Reference.isTouched()) {
return 1;
}
@@ -124,16 +122,13 @@ void DrawViewDetail::onChanged(const App::Property* prop)
}
if (prop == &Reference) {
std::string lblText = "Detail " +
std::string(Reference.getValue());
std::string lblText = "Detail " + std::string(Reference.getValue());
Label.setValue(lblText);
}
if (prop == &Reference ||
prop == &Radius ||
prop == &BaseView) {
if (prop == &Reference || prop == &Radius || prop == &BaseView) {
requestPaint();
}
if (prop == &AnchorPoint) {
if (prop == &AnchorPoint) {
// to see AnchorPoint changes repainting is not enough, we must recompute
recomputeFeature(true);
}
@@ -141,15 +136,15 @@ void DrawViewDetail::onChanged(const App::Property* prop)
DrawViewPart::onChanged(prop);
}
App::DocumentObjectExecReturn *DrawViewDetail::execute()
App::DocumentObjectExecReturn* DrawViewDetail::execute()
{
// Base::Console().Message("DVD::execute() - %s\n", getNameInDocument());
// Base::Console().Message("DVD::execute() - %s\n", getNameInDocument());
if (!keepUpdated()) {
return DrawView::execute();
}
App::DocumentObject* baseObj = BaseView.getValue();
if (!baseObj) {
if (!baseObj) {
return DrawView::execute();
}
@@ -159,15 +154,18 @@ App::DocumentObjectExecReturn *DrawViewDetail::execute()
}
DrawViewPart* dvp = static_cast<DrawViewPart*>(baseObj);
TopoDS_Shape shape = dvp->getShapeForDetail();
DrawViewSection* dvs = nullptr;
TopoDS_Shape shape;
if (dvp->isDerivedFrom(TechDraw::DrawViewSection::getClassTypeId())) {
dvs= static_cast<TechDraw::DrawViewSection*>(dvp);
shape = dvs->getCutShape();
} else {
//getSourceShapeFused will complain if called on section
shape = dvp->getSourceShapeFused();
dvs = static_cast<TechDraw::DrawViewSection*>(dvp);
}
// TopoDS_Shape shape;
// shape = dvs->getCutShape();
// }
// else {
// //getSourceShapeFused will complain if called on section
// shape = dvp->getSourceShapeFused();
// }
if (shape.IsNull()) {
return DrawView::execute();
@@ -178,33 +176,31 @@ App::DocumentObjectExecReturn *DrawViewDetail::execute()
//block touch/onChanged stuff
Base::Vector3d newX = getXDirection();
XDirection.setValue(newX);
XDirection.purgeTouched(); //don't trigger updates!
XDirection.purgeTouched();//don't trigger updates!
//unblock
}
detailExec(shape, dvp, dvs);
addShapes2d();
dvp->requestPaint(); //to refresh detail highlight in base view
dvp->requestPaint();//to refresh detail highlight in base view
return DrawView::execute();
}
//try to create a detail of the solids & shells in shape
//if there are no solids/shells in shape, use the edges in shape
void DrawViewDetail::detailExec(TopoDS_Shape& shape,
DrawViewPart* dvp,
DrawViewSection* dvs)
void DrawViewDetail::detailExec(TopoDS_Shape& shape, DrawViewPart* dvp, DrawViewSection* dvs)
{
if (waitingForHlr() ||
waitingForDetail()) {
if (waitingForHlr() || waitingForDetail()) {
return;
}
//note that &m_detailWatcher in the third parameter is not strictly required, but using the
//4 parameter signature instead of the 3 parameter signature prevents clazy warning:
//https://github.com/KDE/clazy/blob/1.11/docs/checks/README-connect-3arg-lambda.md
connectDetailWatcher = QObject::connect(&m_detailWatcher, &QFutureWatcherBase::finished,
&m_detailWatcher, [this] { this->onMakeDetailFinished(); });
connectDetailWatcher =
QObject::connect(&m_detailWatcher, &QFutureWatcherBase::finished, &m_detailWatcher,
[this] { this->onMakeDetailFinished(); });
m_detailFuture = QtConcurrent::run(this, &DrawViewDetail::makeDetailShape, shape, dvp, dvs);
m_detailWatcher.setFuture(m_detailFuture);
waitingForDetail(true);
@@ -213,9 +209,7 @@ void DrawViewDetail::detailExec(TopoDS_Shape& shape,
//this runs in a separate thread since it can sometimes take a long time
//make a common of the input shape and a cylinder (or prism depending on
//the matting style)
void DrawViewDetail::makeDetailShape(TopoDS_Shape& shape,
DrawViewPart* dvp,
DrawViewSection* dvs)
void DrawViewDetail::makeDetailShape(TopoDS_Shape& shape, DrawViewPart* dvp, DrawViewSection* dvs)
{
showProgressMessage(getNameInDocument(), "is making detail shape");
@@ -232,30 +226,33 @@ void DrawViewDetail::makeDetailShape(TopoDS_Shape& shape,
m_saveDvp = dvp;
m_saveDvs = dvs;
gp_Pnt gpCenter = TechDraw::findCentroid(copyShape,
dirDetail);
gp_Pnt gpCenter = TechDraw::findCentroid(copyShape, dirDetail);
Base::Vector3d shapeCenter = Base::Vector3d(gpCenter.X(), gpCenter.Y(), gpCenter.Z());
m_saveCentroid = shapeCenter; //centroid of original shape
m_saveCentroid = shapeCenter;//centroid of original shape
if (!dvs) {
//section cutShape should already be on origin
copyShape = TechDraw::moveShape(copyShape, //centre shape on origin
-shapeCenter);
copyShape = TechDraw::moveShape(copyShape,//centre shape on origin
-shapeCenter);
}
shapeCenter = Base::Vector3d(0.0, 0.0, 0.0);
m_viewAxis = dvp->getProjectionCS(shapeCenter); //save the CS for later
Base::Vector3d anchor = AnchorPoint.getValue(); //this is a 2D point in unrotated base view coords
anchor = DrawUtil::toR3(m_viewAxis, anchor); //actual anchor coords in R3
m_viewAxis = dvp->getProjectionCS(shapeCenter);//save the CS for later
Base::Vector3d anchor = AnchorPoint.getValue();//this is a 2D point in base view local coords
// double baseRotationRad = dvp->Rotation.getValue() * M_PI / 180.0;
// anchor.RotateZ(baseRotationRad);
anchor = DrawUtil::toR3(m_viewAxis, anchor);//actual anchor coords in R3
Bnd_Box bbxSource;
bbxSource.SetGap(0.0);
BRepBndLib::AddOptimal(copyShape, bbxSource);
double diag = sqrt(bbxSource.SquareExtent());
Base::Vector3d toolPlaneOrigin = anchor + dirDetail * diag * -1.0; //center tool about anchor
Base::Vector3d toolPlaneOrigin = anchor + dirDetail * diag * -1.0;//center tool about anchor
double extrudeLength = 2.0 * toolPlaneOrigin.Length();
gp_Pnt gpnt(toolPlaneOrigin.x, toolPlaneOrigin.y, toolPlaneOrigin.z);
@@ -270,22 +267,26 @@ void DrawViewDetail::makeDetailShape(TopoDS_Shape& shape,
gp_Pln gpln(gpnt, gdir);
BRepBuilderAPI_MakeFace mkFace(gpln, -radius, radius, -radius, radius);
extrusionFace = mkFace.Face();
if(extrusionFace.IsNull()) {
Base::Console().Warning("DVD::makeDetailShape - %s - failed to create tool base face\n", getNameInDocument());
if (extrusionFace.IsNull()) {
Base::Console().Warning("DVD::makeDetailShape - %s - failed to create tool base face\n",
getNameInDocument());
return;
}
tool = BRepPrimAPI_MakePrism(extrusionFace, extrudeDir, false, true).Shape();
if(tool.IsNull()) {
Base::Console().Warning("DVD::makeDetailShape - %s - failed to create tool (prism)\n", getNameInDocument());
if (tool.IsNull()) {
Base::Console().Warning("DVD::makeDetailShape - %s - failed to create tool (prism)\n",
getNameInDocument());
return;
}
} else {
}
else {
//circular mat
gp_Ax2 cs(gpnt, gdir);
BRepPrimAPI_MakeCylinder mkTool(cs, radius, extrudeLength);
tool = mkTool.Shape();
if(tool.IsNull()) {
Base::Console().Warning("DVD::detailExec - %s - failed to create tool (cylinder)\n", getNameInDocument());
if (tool.IsNull()) {
Base::Console().Warning("DVD::detailExec - %s - failed to create tool (cylinder)\n",
getNameInDocument());
return;
}
}
@@ -296,7 +297,7 @@ void DrawViewDetail::makeDetailShape(TopoDS_Shape& shape,
BRep_Builder builder;
TopoDS_Compound pieces;
builder.MakeCompound(pieces);
if (solidCount > 0) {
if (solidCount > 0) {
TopExp_Explorer expl(copyShape, TopAbs_SOLID);
for (; expl.More(); expl.Next()) {
const TopoDS_Solid& s = TopoDS::Solid(expl.Current());
@@ -343,56 +344,48 @@ void DrawViewDetail::makeDetailShape(TopoDS_Shape& shape,
}
if (debugDetail()) {
BRepTools::Write(tool, "DVDTool.brep"); //debug
BRepTools::Write(copyShape, "DVDCopy.brep"); //debug
BRepTools::Write(pieces, "DVDCommon.brep"); //debug
BRepTools::Write(tool, "DVDTool.brep"); //debug
BRepTools::Write(copyShape, "DVDCopy.brep");//debug
BRepTools::Write(pieces, "DVDCommon.brep"); //debug
}
gp_Pnt inputCenter;
try {
//centroid of result
inputCenter = TechDraw::findCentroid(pieces,
dirDetail);
Base::Vector3d centroid(inputCenter.X(),
inputCenter.Y(),
inputCenter.Z());
m_saveCentroid += centroid; //center of massaged shape
inputCenter = TechDraw::findCentroid(pieces, dirDetail);
Base::Vector3d centroid(inputCenter.X(), inputCenter.Y(), inputCenter.Z());
m_saveCentroid += centroid;//center of massaged shape
if ((solidCount > 0) ||
(shellCount > 0)) {
if ((solidCount > 0) || (shellCount > 0)) {
//align shape with detail anchor
TopoDS_Shape centeredShape = TechDraw::moveShape(pieces,
anchor * -1.0);
m_scaledShape = TechDraw::scaleShape(centeredShape,
getScale());
TopoDS_Shape centeredShape = TechDraw::moveShape(pieces, anchor * -1.0);
m_scaledShape = TechDraw::scaleShape(centeredShape, getScale());
if (debugDetail()) {
BRepTools::Write(m_scaledShape, "DVDScaled.brep"); //debug
BRepTools::Write(m_scaledShape, "DVDScaled.brep");//debug
}
} else {
}
else {
//no solids, no shells, do what you can with edges
TopoDS_Shape projectedEdges = projectEdgesOntoFace(copyShape, extrusionFace, gdir);
TopoDS_Shape centeredShape = TechDraw::moveShape(projectedEdges,
anchor * -1.0);
TopoDS_Shape centeredShape = TechDraw::moveShape(projectedEdges, anchor * -1.0);
if (debugDetail()) {
BRepTools::Write(projectedEdges, "DVDProjectedEdges.brep"); //debug
BRepTools::Write(centeredShape, "DVDCenteredShape.brep"); //debug
BRepTools::Write(projectedEdges, "DVDProjectedEdges.brep");//debug
BRepTools::Write(centeredShape, "DVDCenteredShape.brep"); //debug
}
m_scaledShape = TechDraw::scaleShape(centeredShape,
getScale());
m_scaledShape = TechDraw::scaleShape(centeredShape, getScale());
}
Base::Vector3d stdOrg(0.0, 0.0, 0.0);
m_viewAxis = dvp->getProjectionCS(stdOrg);
if (!DrawUtil::fpCompare(Rotation.getValue(), 0.0)) {
m_scaledShape = TechDraw::rotateShape(m_scaledShape,
m_viewAxis,
Rotation.getValue());
m_scaledShape = TechDraw::rotateShape(m_scaledShape, m_viewAxis, Rotation.getValue());
}
} //end try block
}//end try block
catch (Standard_Failure& e1) {
Base::Console().Message("DVD::makeDetailShape - failed to create detail %s - %s **\n", getNameInDocument(), e1.GetMessageString());
Base::Console().Message("DVD::makeDetailShape - failed to create detail %s - %s **\n",
getNameInDocument(), e1.GetMessageString());
return;
}
@@ -401,11 +394,12 @@ void DrawViewDetail::makeDetailShape(TopoDS_Shape& shape,
void DrawViewDetail::postHlrTasks(void)
{
// Base::Console().Message("DVD::postHlrTasks()\n");
// Base::Console().Message("DVD::postHlrTasks()\n");
DrawViewPart::postHlrTasks();
geometryObject->pruneVertexGeom(Base::Vector3d(0.0, 0.0, 0.0),
Radius.getValue() * getScale()); //remove vertices beyond clipradius
Radius.getValue()
* getScale());//remove vertices beyond clipradius
//second pass if required
if (ScaleType.isValue("Automatic") && !checkFit()) {
@@ -424,28 +418,24 @@ void DrawViewDetail::onMakeDetailFinished(void)
QObject::disconnect(connectDetailWatcher);
//ancestor's buildGeometryObject will run HLR and face finding in a separate thread
m_tempGeometryObject = buildGeometryObject(m_scaledShape, m_viewAxis);
m_tempGeometryObject = buildGeometryObject(m_scaledShape, m_viewAxis);
}
bool DrawViewDetail::waitingForResult() const
{
if (DrawViewPart::waitingForResult() ||
waitingForDetail()) {
if (DrawViewPart::waitingForResult() || waitingForDetail()) {
return true;
}
return false;
}
TopoDS_Shape DrawViewDetail::projectEdgesOntoFace(TopoDS_Shape &edgeShape,
TopoDS_Face &projFace,
TopoDS_Shape DrawViewDetail::projectEdgesOntoFace(TopoDS_Shape& edgeShape, TopoDS_Face& projFace,
gp_Dir& projDir)
{
BRep_Builder builder;
TopoDS_Compound edges;
builder.MakeCompound(edges);
TopExp_Explorer Ex(edgeShape, TopAbs_EDGE);
while (Ex.More())
{
while (Ex.More()) {
TopoDS_Edge e = TopoDS::Edge(Ex.Current());
BRepProj_Projection mkProj(e, projFace, projDir);
if (mkProj.IsDone()) {
@@ -454,7 +444,7 @@ TopoDS_Shape DrawViewDetail::projectEdgesOntoFace(TopoDS_Shape &edgeShape,
Ex.Next();
}
if (debugDetail()) {
BRepTools::Write(edges, "DVDEdges.brep"); //debug
BRepTools::Write(edges, "DVDEdges.brep");//debug
}
return TopoDS_Shape(std::move(edges));
@@ -467,22 +457,22 @@ std::vector<DrawViewDetail*> DrawViewDetail::getDetailRefs() const
return std::vector<DrawViewDetail*>();
}
double DrawViewDetail::getFudgeRadius()
{
return Radius.getValue() * m_fudge;
}
double DrawViewDetail::getFudgeRadius() { return Radius.getValue() * m_fudge; }
bool DrawViewDetail::debugDetail() const
{
Base::Reference<ParameterGrp> hGrp = App::GetApplication().GetUserParameter()
.GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/TechDraw/debug");
Base::Reference<ParameterGrp> hGrp = App::GetApplication()
.GetUserParameter()
.GetGroup("BaseApp")
->GetGroup("Preferences")
->GetGroup("Mod/TechDraw/debug");
return hGrp->GetBool("debugDetail", false);
}
void DrawViewDetail::unsetupObject()
{
// Base::Console().Message("DVD::unsetupObject()\n");
// Base::Console().Message("DVD::unsetupObject()\n");
App::DocumentObject* baseObj = BaseView.getValue();
DrawView* base = dynamic_cast<DrawView*>(baseObj);
if (base) {
@@ -490,20 +480,20 @@ void DrawViewDetail::unsetupObject()
}
}
void DrawViewDetail::getParameters()
{
}
void DrawViewDetail::getParameters() {}
// Python Drawing feature ---------------------------------------------------------
namespace App {
namespace App
{
/// @cond DOXERR
PROPERTY_SOURCE_TEMPLATE(TechDraw::DrawViewDetailPython, TechDraw::DrawViewDetail)
template<> const char* TechDraw::DrawViewDetailPython::getViewProviderName() const {
template<> const char* TechDraw::DrawViewDetailPython::getViewProviderName() const
{
return "TechDrawGui::ViewProviderViewPart";
}
/// @endcond
// explicit template instantiation
template class TechDrawExport FeaturePythonT<TechDraw::DrawViewDetail>;
}
}// namespace App