[TD]fix 10013 detail of sketch

This commit is contained in:
wandererfan
2023-07-31 13:58:49 -04:00
committed by WandererFan
parent 8e600f0a44
commit a51e46775f
6 changed files with 99 additions and 119 deletions

View File

@@ -566,6 +566,24 @@ TopoDS_Shape DrawUtil::vectorToCompound(std::vector<TopoDS_Wire> vecIn, bool inv
return compOut;
}
// construct a compound shape from a list of shapes
// this version needs a different name since edges/wires are shapes
TopoDS_Shape DrawUtil::shapeVectorToCompound(std::vector<TopoDS_Shape> vecIn, bool invert)
{
BRep_Builder builder;
TopoDS_Compound compOut;
builder.MakeCompound(compOut);
for (auto& v : vecIn) {
if (!v.IsNull()) {
builder.Add(compOut, v);
}
}
if (invert) {
return TechDraw::mirrorShape(compOut);
}
return compOut;
}
//constructs a list of edges from a shape
std::vector<TopoDS_Edge> DrawUtil::shapeToVector(TopoDS_Shape shapeIn)
{

View File

@@ -130,6 +130,7 @@ public:
static TopoDS_Shape vectorToCompound(std::vector<TopoDS_Edge> vecIn, bool invert = true);
static TopoDS_Shape vectorToCompound(std::vector<TopoDS_Wire> vecIn, bool invert = true);
static TopoDS_Shape shapeVectorToCompound(std::vector<TopoDS_Shape> vecIn, bool invert = true);
static std::vector<TopoDS_Edge> shapeToVector(TopoDS_Shape shapeIn);
static Base::Vector3d toR3(const gp_Ax2& fromSystem, const Base::Vector3d& fromPoint);

View File

@@ -60,6 +60,7 @@
#include "DrawViewSection.h"
#include "GeometryObject.h"
#include "Preferences.h"
#include "ShapeUtils.h"
using namespace TechDraw;
@@ -205,9 +206,6 @@ void DrawViewDetail::makeDetailShape(const TopoDS_Shape& shape, DrawViewPart* dv
Base::Vector3d dirDetail = dvp->Direction.getValue();
double radius = getFudgeRadius();
int solidCount = DrawUtil::countSubShapes(shape, TopAbs_SOLID);
int shellCount = DrawUtil::countSubShapes(shape, TopAbs_SHELL);
//make a copy of the input shape so we don't inadvertently change it
BRepBuilderAPI_Copy BuilderCopy(shape);
TopoDS_Shape copyShape = BuilderCopy.Shape();
@@ -230,12 +228,9 @@ void DrawViewDetail::makeDetailShape(const TopoDS_Shape& shape, DrawViewPart* dv
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);
@@ -280,105 +275,38 @@ void DrawViewDetail::makeDetailShape(const TopoDS_Shape& shape, DrawViewPart* dv
}
}
//for each solid and shell in the input shape, make a common with the tool and
//add the result to a compound. This avoids issues with some geometry errors in the
//input shape.
BRep_Builder builder;
TopoDS_Compound pieces;
builder.MakeCompound(pieces);
if (solidCount > 0) {
TopExp_Explorer expl(copyShape, TopAbs_SOLID);
for (; expl.More(); expl.Next()) {
const TopoDS_Solid& s = TopoDS::Solid(expl.Current());
BRepAlgoAPI_Common mkCommon(s, tool);
if (!mkCommon.IsDone()) {
continue;
}
if (mkCommon.Shape().IsNull()) {
continue;
}
//this might be overkill for piecewise algo
//Did we get at least 1 solid?
TopExp_Explorer xp;
xp.Init(mkCommon.Shape(), TopAbs_SOLID);
if (xp.More() != Standard_True) {
continue;
}
builder.Add(pieces, mkCommon.Shape());
}
}
if (shellCount > 0) {
TopExp_Explorer expl(copyShape, TopAbs_SHELL);
for (; expl.More(); expl.Next()) {
const TopoDS_Shell& s = TopoDS::Shell(expl.Current());
BRepAlgoAPI_Common mkCommon(s, tool);
if (!mkCommon.IsDone()) {
continue;
}
if (mkCommon.Shape().IsNull()) {
continue;
}
//this might be overkill for piecewise algo
//Did we get at least 1 shell?
TopExp_Explorer xp;
xp.Init(mkCommon.Shape(), TopAbs_SHELL);
if (xp.More() != Standard_True) {
continue;
}
builder.Add(pieces, mkCommon.Shape());
}
BRepAlgoAPI_Common mkCommon(copyShape, tool);
if (!mkCommon.IsDone() || mkCommon.Shape().IsNull()) {
Base::Console().Warning("DVD::detailExec - %s - failed to create detail shape\n",
getNameInDocument());
return;
}
// save the detail shape for further processing
m_detailShape = pieces;
m_detailShape = mkCommon.Shape();
if (debugDetail()) {
BRepTools::Write(tool, "DVDTool.brep"); //debug
BRepTools::Write(copyShape, "DVDCopy.brep");//debug
BRepTools::Write(pieces, "DVDCommon.brep"); //debug
BRepTools::Write(m_detailShape, "DVDCommon.brep"); //debug
}
gp_Pnt inputCenter;
try {
//centroid of result
inputCenter = ShapeUtils::findCentroid(pieces, dirDetail);
Base::Vector3d centroid(inputCenter.X(), inputCenter.Y(), inputCenter.Z());
m_saveCentroid += centroid;//center of massaged shape
gp_Pnt inputCenter = ShapeUtils::findCentroid(m_detailShape, dirDetail);
Base::Vector3d centroid(inputCenter.X(), inputCenter.Y(), inputCenter.Z());
m_saveCentroid += centroid;//center of massaged shape
//align shape with detail anchor
TopoDS_Shape centeredShape = ShapeUtils::moveShape(m_detailShape, anchor * -1.0);
m_scaledShape = ShapeUtils::scaleShape(centeredShape, getScale());
if ((solidCount > 0) || (shellCount > 0)) {
//align shape with detail anchor
TopoDS_Shape centeredShape = ShapeUtils::moveShape(pieces, anchor * -1.0);
m_scaledShape = ShapeUtils::scaleShape(centeredShape, getScale());
if (debugDetail()) {
BRepTools::Write(m_scaledShape, "DVDScaled.brep");//debug
}
}
else {
//no solids, no shells, do what you can with edges
TopoDS_Shape projectedEdges = projectEdgesOntoFace(copyShape, extrusionFace, gdir);
TopoDS_Shape centeredShape = ShapeUtils::moveShape(projectedEdges, anchor * -1.0);
if (debugDetail()) {
BRepTools::Write(projectedEdges, "DVDProjectedEdges.brep");//debug
BRepTools::Write(centeredShape, "DVDCenteredShape.brep"); //debug
}
m_scaledShape = ShapeUtils::scaleShape(centeredShape, getScale());
}
if (debugDetail()) {
BRepTools::Write(m_scaledShape, "DVDScaled.brep");//debug
}
Base::Vector3d stdOrg(0.0, 0.0, 0.0);
m_viewAxis = dvp->getProjectionCS(stdOrg);
Base::Vector3d stdOrg(0.0, 0.0, 0.0);
m_viewAxis = dvp->getProjectionCS(stdOrg);
if (!DrawUtil::fpCompare(Rotation.getValue(), 0.0)) {
m_scaledShape = ShapeUtils::rotateShape(m_scaledShape, m_viewAxis, Rotation.getValue());
}
}//end try block
catch (Standard_Failure& e1) {
Base::Console().Message("DVD::makeDetailShape - failed to create detail %s - %s **\n",
getNameInDocument(), e1.GetMessageString());
return;
if (!DrawUtil::fpCompare(Rotation.getValue(), 0.0)) {
m_scaledShape = ShapeUtils::rotateShape(m_scaledShape, m_viewAxis, Rotation.getValue());
}
showProgressMessage(getNameInDocument(), "has finished making detail shape");

View File

@@ -22,6 +22,18 @@
* *
***************************************************************************/
//===========================================================================
// DrawViewPart overview
//===========================================================================
//
// 1) get the shapes from the source objects
// 2) center, scale and rotate the shapes
// 3) project the shape using the OCC HLR algorithms
// 4) add cosmetic and other objects that don't participate in hlr
// 5) find the closed regions (faces) in the edges returned by hlr
// everything else is mostly providing services to other objects, such as the
// actual drawing routines in Gui
#include "PreCompiled.h"
#ifndef _PreComp_
@@ -82,11 +94,6 @@
using namespace TechDraw;
using DU = DrawUtil;
//===========================================================================
// DrawViewPart
//===========================================================================
PROPERTY_SOURCE_WITH_EXTENSIONS(TechDraw::DrawViewPart, TechDraw::DrawView)
DrawViewPart::DrawViewPart(void)
@@ -157,6 +164,8 @@ DrawViewPart::~DrawViewPart()
removeAllReferencesFromGeom();
}
//! returns a compound of all the shapes from the DocumentObjects in the Source &
//! XSource property lists
TopoDS_Shape DrawViewPart::getSourceShape(bool fuse) const
{
// Base::Console().Message("DVP::getSourceShape()\n");
@@ -170,15 +179,15 @@ TopoDS_Shape DrawViewPart::getSourceShape(bool fuse) const
return ShapeExtractor::getShapes(links);
}
// deliver a shape appropriate for making a detail view based on this view
// TODO: why does dvp do the thinking for detail, but section picks its own
// version of the shape? Should we have a getShapeForSection?
//! deliver a shape appropriate for making a detail view based on this view
//! TODO: why does dvp do the thinking for detail, but section picks its own
//! version of the shape? Should we have a getShapeForSection?
TopoDS_Shape DrawViewPart::getShapeForDetail() const
{
return ShapeUtils::rotateShape(getSourceShape(true), getProjectionCS(), Rotation.getValue());
}
// combine the regular links and xlinks into a single list
//! combine the regular links and xlinks into a single list
std::vector<App::DocumentObject*> DrawViewPart::getAllSources() const
{
// Base::Console().Message("DVP::getAllSources()\n");
@@ -192,8 +201,8 @@ std::vector<App::DocumentObject*> DrawViewPart::getAllSources() const
return result;
}
//pick supported 2d shapes out of the Source properties and
//add them directly to the geometry without going through HLR
//! pick supported 2d shapes out of the Source properties and
//! add them directly to the geometry without going through HLR
void DrawViewPart::addShapes2d(void)
{
std::vector<TopoDS_Shape> shapes = ShapeExtractor::getShapes2d(getAllSources());
@@ -300,7 +309,7 @@ void DrawViewPart::partExec(TopoDS_Shape& shape)
}
}
//prepare the shape for HLR processing by centering, scaling and rotating it
//! prepare the shape for HLR processing by centering, scaling and rotating it
GeometryObjectPtr DrawViewPart::makeGeometryForShape(TopoDS_Shape& shape)
{
// Base::Console().Message("DVP::makeGeometryForShape() - %s\n", getNameInDocument());
@@ -320,7 +329,7 @@ GeometryObjectPtr DrawViewPart::makeGeometryForShape(TopoDS_Shape& shape)
return buildGeometryObject(localShape, getProjectionCS());
}
//Modify a shape by centering, scaling and rotating and return the centered (but not rotated) shape
//! Modify a shape by centering, scaling and rotating and return the centered (but not rotated) shape
TopoDS_Shape DrawViewPart::centerScaleRotate(DrawViewPart* dvp, TopoDS_Shape& inOutShape,
Base::Vector3d centroid)
{
@@ -339,7 +348,7 @@ TopoDS_Shape DrawViewPart::centerScaleRotate(DrawViewPart* dvp, TopoDS_Shape& in
return centeredShape;
}
//create a geometry object and trigger the HLR process in another thread
//! create a geometry object and trigger the HLR process in another thread
TechDraw::GeometryObjectPtr DrawViewPart::buildGeometryObject(TopoDS_Shape& shape,
const gp_Ax2& viewAxis)
{
@@ -386,7 +395,7 @@ TechDraw::GeometryObjectPtr DrawViewPart::buildGeometryObject(TopoDS_Shape& shap
return go;
}
//continue processing after hlr thread completes
//! continue processing after hlr thread completes
void DrawViewPart::onHlrFinished(void)
{
// Base::Console().Message("DVP::onHlrFinished() - %s\n", getNameInDocument());
@@ -436,7 +445,7 @@ void DrawViewPart::onHlrFinished(void)
}
}
//run any tasks that need to been done after geometry is available
//! run any tasks that need to been done after geometry is available
void DrawViewPart::postHlrTasks(void)
{
// Base::Console().Message("DVP::postHlrTasks() - %s\n", getNameInDocument());

View File

@@ -41,6 +41,7 @@
#include <Base/Placement.h>
#include <Mod/Part/App/PartFeature.h>
#include <Mod/Part/App/PrimitiveFeature.h>
//#include <Mod/Sketcher/App/SketchObject.h>
#include "ShapeExtractor.h"
#include "DrawUtil.h"
@@ -50,12 +51,12 @@
using namespace TechDraw;
using DU = DrawUtil;
std::vector<TopoDS_Shape> ShapeExtractor::getShapes2d(const std::vector<App::DocumentObject*> links)
std::vector<TopoDS_Shape> ShapeExtractor::getShapes2d(const std::vector<App::DocumentObject*> links, bool overridePref)
{
// Base::Console().Message("SE::getShapes2d()\n");
std::vector<TopoDS_Shape> shapes2d;
if (!prefAdd2d()) {
if (!prefAdd2d() && !overridePref) {
return shapes2d;
}
for (auto& l:links) {
@@ -89,12 +90,15 @@ std::vector<TopoDS_Shape> ShapeExtractor::getShapes2d(const std::vector<App::Doc
return shapes2d;
}
TopoDS_Shape ShapeExtractor::getShapes(const std::vector<App::DocumentObject*> links)
TopoDS_Shape ShapeExtractor::getShapes(const std::vector<App::DocumentObject*> links, bool include2d)
{
// Base::Console().Message("SE::getShapes() - links in: %d\n", links.size());
std::vector<TopoDS_Shape> sourceShapes;
for (auto& l:links) {
if (is2dObject(l) && !include2d) {
continue;
}
if (l->getTypeId().isDerivedFrom(App::Link::getClassTypeId())) {
App::Link* xLink = dynamic_cast<App::Link*>(l);
std::vector<TopoDS_Shape> xShapes = getXShapes(xLink);
@@ -313,7 +317,8 @@ std::vector<TopoDS_Shape> ShapeExtractor::getShapesFromObject(const App::Documen
TopoDS_Shape ShapeExtractor::getShapesFused(const std::vector<App::DocumentObject*> links)
{
// Base::Console().Message("SE::getShapesFused()\n");
TopoDS_Shape baseShape = getShapes(links);
// get only the 3d shapes and fuse them
TopoDS_Shape baseShape = getShapes(links, false);
if (!baseShape.IsNull()) {
TopoDS_Iterator it(baseShape);
TopoDS_Shape fusedShape = it.Value();
@@ -330,6 +335,15 @@ TopoDS_Shape ShapeExtractor::getShapesFused(const std::vector<App::DocumentObjec
}
baseShape = fusedShape;
}
// if there are 2d shapes in the links they will not fuse with the 3d shapes,
// so instead we return a compound of the fused 3d shapes and the 2d shapes
std::vector<TopoDS_Shape> shapes2d = getShapes2d(links, true);
if (!shapes2d.empty()) {
shapes2d.push_back(baseShape);
return DrawUtil::shapeVectorToCompound(shapes2d);
}
return baseShape;
}
@@ -361,11 +375,21 @@ TopoDS_Shape ShapeExtractor::stripInfiniteShapes(TopoDS_Shape inShape)
bool ShapeExtractor::is2dObject(App::DocumentObject* obj)
{
bool result = false;
if (isEdgeType(obj) || isPointType(obj)) {
result = true;
// TODO:: the check for an object being a sketch should be done as in the commented
// if statement below. To do this, we need to include Mod/Sketcher/SketchObject.h,
// but that makes TechDraw dependent on Eigen libraries which we don't use. As a
// workaround we will inspect the object's class name.
// if (obj->isDerivedFrom(Sketcher::SketchObject::getClassTypeId())) {
std::string objTypeName = obj->getTypeId().getName();
std::string sketcherToken("Sketcher");
if (objTypeName.find(sketcherToken) != std::string::npos) {
return true;
}
return result;
if (isEdgeType(obj) || isPointType(obj)) {
return true;
}
return false;
}
//skip edges for now.

View File

@@ -39,8 +39,8 @@ namespace TechDraw
class TechDrawExport ShapeExtractor
{
public:
static TopoDS_Shape getShapes(const std::vector<App::DocumentObject*> links);
static std::vector<TopoDS_Shape> getShapes2d(const std::vector<App::DocumentObject*> links);
static TopoDS_Shape getShapes(const std::vector<App::DocumentObject*> links, bool include2d = true);
static std::vector<TopoDS_Shape> getShapes2d(const std::vector<App::DocumentObject*> links, bool overridePref = false);
static std::vector<TopoDS_Shape> getXShapes(const App::Link* xLink);
static std::vector<TopoDS_Shape> getShapesFromObject(const App::DocumentObject* docObj);
static TopoDS_Shape getShapesFused(const std::vector<App::DocumentObject*> links);