[Import]Flatten sketch before dxf export.
This commit is contained in:
@@ -51,6 +51,7 @@
|
||||
#endif
|
||||
|
||||
#include "dxf/ImpExpDxf.h"
|
||||
#include "SketchExportHelper.h"
|
||||
#include <App/Application.h>
|
||||
#include <App/Document.h>
|
||||
#include <App/DocumentObjectPy.h>
|
||||
@@ -427,8 +428,10 @@ private:
|
||||
return Py::None();
|
||||
}
|
||||
|
||||
|
||||
Py::Object writeDXFShape(const Py::Tuple& args)
|
||||
{
|
||||
Base::Console().Message("Imp:writeDXFShape()\n");
|
||||
PyObject* shapeObj = nullptr;
|
||||
char* fname = nullptr;
|
||||
std::string filePath;
|
||||
@@ -592,11 +595,19 @@ private:
|
||||
PyObject* item = (*it).ptr();
|
||||
App::DocumentObject* obj =
|
||||
static_cast<App::DocumentObjectPy*>(item)->getDocumentObjectPtr();
|
||||
Part::Feature* part = static_cast<Part::Feature*>(obj);
|
||||
layerName = part->getNameInDocument();
|
||||
layerName = obj->getNameInDocument();
|
||||
writer.setLayerName(layerName);
|
||||
const TopoDS_Shape& shape = part->Shape.getValue();
|
||||
writer.exportShape(shape);
|
||||
TopoDS_Shape shapeToExport;
|
||||
if (SketchExportHelper::isSketch(obj)) {
|
||||
// project sketch along sketch Z via hlrProjector to get geometry on XY plane
|
||||
shapeToExport = SketchExportHelper::getFlatSketchXY(obj);
|
||||
} else {
|
||||
// do we know that obj is a Part::Feature? is this checked somewhere before this?
|
||||
// this should be a located shape??
|
||||
Part::Feature* part = static_cast<Part::Feature*>(obj);
|
||||
shapeToExport = part->Shape.getValue();
|
||||
}
|
||||
writer.exportShape(shapeToExport);
|
||||
}
|
||||
}
|
||||
writer.endRun();
|
||||
@@ -620,6 +631,8 @@ private:
|
||||
filePath = std::string(fname);
|
||||
layerName = "none";
|
||||
PyMem_Free(fname);
|
||||
App::DocumentObject* obj = static_cast<App::DocumentObjectPy*>(docObj)->getDocumentObjectPtr();
|
||||
Base::Console().Message("Imp:writeDXFObject - docObj: %s\n", obj->getNameInDocument());
|
||||
|
||||
if ((versionParm == 12) || (versionParm == 14)) {
|
||||
versionOverride = true;
|
||||
@@ -644,11 +657,19 @@ private:
|
||||
writer.init();
|
||||
App::DocumentObject* obj =
|
||||
static_cast<App::DocumentObjectPy*>(docObj)->getDocumentObjectPtr();
|
||||
Part::Feature* part = static_cast<Part::Feature*>(obj);
|
||||
layerName = part->getNameInDocument();
|
||||
layerName = obj->getNameInDocument();
|
||||
writer.setLayerName(layerName);
|
||||
const TopoDS_Shape& shape = part->Shape.getValue();
|
||||
writer.exportShape(shape);
|
||||
TopoDS_Shape shapeToExport;
|
||||
if (SketchExportHelper::isSketch(obj)) {
|
||||
// project sketch along sketch Z via hlrProjector to get geometry on XY plane
|
||||
shapeToExport = SketchExportHelper::getFlatSketchXY(obj);
|
||||
} else {
|
||||
// TODO: do we know that obj is a Part::Feature? is this checked somewhere before this?
|
||||
// TODO: this should be a located shape??
|
||||
Part::Feature* part = static_cast<Part::Feature*>(obj);
|
||||
shapeToExport = part->Shape.getValue();
|
||||
}
|
||||
writer.exportShape(shapeToExport);
|
||||
writer.endRun();
|
||||
return Py::None();
|
||||
}
|
||||
|
||||
@@ -50,6 +50,8 @@ SET(Import_SRCS
|
||||
WriterIges.h
|
||||
WriterStep.cpp
|
||||
WriterStep.h
|
||||
SketchExportHelper.cpp
|
||||
SketchExportHelper.h
|
||||
dxf/ImpExpDxf.cpp
|
||||
dxf/ImpExpDxf.h
|
||||
dxf/dxf.cpp
|
||||
|
||||
115
src/Mod/Import/App/SketchExportHelper.cpp
Normal file
115
src/Mod/Import/App/SketchExportHelper.cpp
Normal file
@@ -0,0 +1,115 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 WandererFan <wandererfan@gmail.com> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
//! a class to assist with exporting sketches to dxf
|
||||
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
#include <HLRBRep_Algo.hxx>
|
||||
#include <HLRAlgo_Projector.hxx>
|
||||
#include <HLRBRep_HLRToShape.hxx>
|
||||
#include <BRep_Builder.hxx>
|
||||
#include <BRepBuilderAPI_Transform.hxx>
|
||||
#endif
|
||||
|
||||
#include <App/DocumentObject.h>
|
||||
#include <Base/Placement.h>
|
||||
#include <Base/Vector3D.h>
|
||||
|
||||
#include <Mod/Part/App/PartFeature.h>
|
||||
|
||||
#include "SketchExportHelper.h"
|
||||
|
||||
using namespace Import;
|
||||
|
||||
//! project a shape so that it is represented as a flat shape on the XY plane. Z coordinate information
|
||||
//! is lost in this process, so it should only be used for flat objects like sketches.
|
||||
//! Note: this only returns hard and outline edges. Seam, smooth, isoparametric and hidden lines are not returned.
|
||||
TopoDS_Shape SketchExportHelper::projectShape(const TopoDS_Shape& inShape, const gp_Ax2& projectionCS)
|
||||
{
|
||||
Handle(HLRBRep_Algo) brep_hlr = new HLRBRep_Algo();
|
||||
brep_hlr->Add(inShape);
|
||||
HLRAlgo_Projector projector(projectionCS);
|
||||
brep_hlr->Projector(projector);
|
||||
brep_hlr->Update();
|
||||
brep_hlr->Hide();
|
||||
HLRBRep_HLRToShape hlrToShape(brep_hlr);
|
||||
BRep_Builder builder;
|
||||
TopoDS_Compound comp;
|
||||
builder.MakeCompound(comp);
|
||||
if (!hlrToShape.VCompound().IsNull()) {
|
||||
builder.Add(comp, hlrToShape.VCompound());
|
||||
}
|
||||
if (!hlrToShape.OutLineVCompound().IsNull()) {
|
||||
builder.Add(comp, hlrToShape.OutLineVCompound());
|
||||
}
|
||||
return comp;
|
||||
}
|
||||
|
||||
|
||||
//! true if obj is a sketch
|
||||
bool SketchExportHelper::isSketch(App::DocumentObject* obj)
|
||||
{
|
||||
// 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 Import 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");
|
||||
return objTypeName.find(sketcherToken) != std::string::npos;
|
||||
}
|
||||
|
||||
|
||||
//! return a version of a sketch's geometry mapped to the OXYZ coordinate system
|
||||
//! preferred by dxf
|
||||
TopoDS_Shape SketchExportHelper::getFlatSketchXY(App::DocumentObject* obj)
|
||||
{
|
||||
// since we can't reference Sketcher module here, we will cast obj to
|
||||
// a Part::Feature instead
|
||||
auto sketch = dynamic_cast<Part::Feature*>(obj);
|
||||
if ( !sketch || !isSketch(obj)){
|
||||
return {};
|
||||
}
|
||||
|
||||
auto plm = sketch->Placement.getValue();
|
||||
Base::Rotation rot = plm.getRotation();
|
||||
|
||||
//get the sketch normal
|
||||
Base::Vector3d stdZ{0.0, 0.0, 1.0};
|
||||
Base::Vector3d sketchNormal;
|
||||
rot.multVec(stdZ, sketchNormal);
|
||||
Base::Vector3d stdX{1.0, 0.0, 0.0};
|
||||
Base::Vector3d sketchX;
|
||||
rot.multVec(stdX, sketchX);
|
||||
|
||||
//get the sketch origin
|
||||
Base::Vector3d position = plm.getPosition();
|
||||
gp_Ax2 projectionCS(gp_Pnt(position.x, position.y, position.z),
|
||||
gp_Dir(sketchNormal.x, sketchNormal.y, sketchNormal.z),
|
||||
gp_Dir(sketchX.x, sketchX.y, sketchX.z));
|
||||
const TopoDS_Shape& shape = sketch->Shape.getValue();
|
||||
return projectShape(shape, projectionCS);
|
||||
}
|
||||
|
||||
46
src/Mod/Import/App/SketchExportHelper.h
Normal file
46
src/Mod/Import/App/SketchExportHelper.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 WandererFan <wandererfan@gmail.com> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
//! a class to assist with exporting sketches to dxf
|
||||
|
||||
#include <Mod/Import/ImportGlobal.h>
|
||||
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <gp_Ax2.hxx>
|
||||
|
||||
namespace App
|
||||
{
|
||||
class DocumentObject;
|
||||
}
|
||||
|
||||
namespace Import
|
||||
{
|
||||
|
||||
class ImportExport SketchExportHelper
|
||||
{
|
||||
public:
|
||||
static TopoDS_Shape projectShape(const TopoDS_Shape& inShape, const gp_Ax2& projectionCS);
|
||||
static bool isSketch(App::DocumentObject* obj);
|
||||
static TopoDS_Shape getFlatSketchXY(App::DocumentObject* obj);
|
||||
};
|
||||
|
||||
}
|
||||
@@ -656,7 +656,7 @@ void CDxfWrite::writePolyline(const LWPolyDataOut& pd)
|
||||
(*m_ssEntity) << " 20" << endl;
|
||||
(*m_ssEntity) << p.y << endl;
|
||||
(*m_ssEntity) << " 30" << endl;
|
||||
(*m_ssEntity) << "0.0" << endl;
|
||||
(*m_ssEntity) << p.z << endl;
|
||||
}
|
||||
(*m_ssEntity) << " 0" << endl;
|
||||
(*m_ssEntity) << "SEQEND" << endl;
|
||||
@@ -692,7 +692,10 @@ void CDxfWrite::writePoint(const double* point)
|
||||
(*m_ssEntity) << point[2] << endl; // Z in WCS coordinates
|
||||
}
|
||||
|
||||
//! arc from 3 points - start, end, center. dir true if arc is AntiClockwise. unspecified assumption is that
|
||||
//! points are on XY plane in coord system OXYZ.
|
||||
void CDxfWrite::writeArc(const double* start, const double* end, const double* center, bool dir)
|
||||
|
||||
{
|
||||
double ax = start[0] - center[0];
|
||||
double ay = start[1] - center[1];
|
||||
@@ -766,8 +769,8 @@ void CDxfWrite::writeCircle(const double* center, double radius)
|
||||
(*m_ssEntity) << center[0] << endl; // X in WCS coordinates
|
||||
(*m_ssEntity) << " 20" << endl;
|
||||
(*m_ssEntity) << center[1] << endl; // Y in WCS coordinates
|
||||
// (*m_ssEntity) << " 30" << endl;
|
||||
// (*m_ssEntity) << center[2] << endl; // Z in WCS coordinates
|
||||
(*m_ssEntity) << " 30" << endl;
|
||||
(*m_ssEntity) << center[2] << endl; // Z in WCS coordinates
|
||||
(*m_ssEntity) << " 40" << endl; //
|
||||
(*m_ssEntity) << radius << endl; // Radius
|
||||
}
|
||||
@@ -817,8 +820,7 @@ void CDxfWrite::writeEllipse(const double* center,
|
||||
(*m_ssEntity) << " 31" << endl;
|
||||
(*m_ssEntity) << m.z << endl; // Major Z
|
||||
(*m_ssEntity) << " 40" << endl; //
|
||||
(*m_ssEntity) << ratio
|
||||
<< endl; // Ratio
|
||||
(*m_ssEntity) << ratio << endl; // Ratio
|
||||
// (*m_ssEntity) << "210" << endl; //extrusion dir??
|
||||
// (*m_ssEntity) << "0" << endl;
|
||||
// (*m_ssEntity) << "220" << endl;
|
||||
|
||||
Reference in New Issue
Block a user