[TD]migrate DrawingWB projection functions to TechDrawWB
This commit is contained in:
committed by
WandererFan
parent
81fa1d6a27
commit
aa6f8c4b14
@@ -65,6 +65,8 @@
|
||||
|
||||
#include "CosmeticExtension.h"
|
||||
|
||||
#include "FeatureProjection.h"
|
||||
|
||||
namespace TechDraw {
|
||||
extern PyObject* initModule();
|
||||
}
|
||||
@@ -130,6 +132,8 @@ PyMOD_INIT_FUNC(TechDraw)
|
||||
TechDraw::CosmeticExtension ::init();
|
||||
TechDraw::CosmeticExtensionPython::init();
|
||||
|
||||
TechDraw::FeatureProjection::init();
|
||||
|
||||
// are these python init calls required? some modules don't have them
|
||||
// Python Types
|
||||
TechDraw::DrawPagePython ::init();
|
||||
|
||||
@@ -34,9 +34,12 @@
|
||||
#include <gp_Vec.hxx>
|
||||
#include <BRep_Builder.hxx>
|
||||
#include <BRepBuilderAPI_Transform.hxx>
|
||||
|
||||
#endif
|
||||
|
||||
#include <Mod/TechDraw/TechDrawGlobal.h>
|
||||
|
||||
#include <boost/regex.hpp>
|
||||
|
||||
#include <CXX/Extensions.hxx>
|
||||
#include <CXX/Objects.hxx>
|
||||
|
||||
@@ -58,7 +61,6 @@
|
||||
#include <Mod/Part/App/TopoShapeCompoundPy.h>
|
||||
#include <Mod/Part/App/OCCError.h>
|
||||
|
||||
#include <Mod/Drawing/App/DrawingExport.h>
|
||||
#include <Mod/Import/App/ImpExpDxf.h>
|
||||
|
||||
#include "DrawProjectSplit.h"
|
||||
@@ -78,6 +80,10 @@
|
||||
#include "HatchLine.h"
|
||||
#include "DrawGeomHatch.h"
|
||||
|
||||
#include "TechDrawExport.h"
|
||||
#include "ProjectionAlgos.h"
|
||||
|
||||
|
||||
namespace TechDraw {
|
||||
//module level static C++ functions go here
|
||||
}
|
||||
@@ -90,8 +96,39 @@ using Part::TopoShapeWirePy;
|
||||
using Part::TopoShapeCompoundPy;
|
||||
using Import::ImpExpDxfWrite;
|
||||
|
||||
using TechDraw::ProjectionAlgos;
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace TechDraw {
|
||||
|
||||
/** Copies a Python dictionary of Python strings to a C++ container.
|
||||
*
|
||||
* After the function call, the key-value pairs of the Python
|
||||
* dictionary are copied into the target buffer as C++ pairs
|
||||
* (pair<string, string>).
|
||||
*
|
||||
* @param sourceRange is a Python dictionary (Py::Dict). Both, the
|
||||
* keys and the values must be Python strings.
|
||||
*
|
||||
* @param targetIt refers to where the data should be inserted. Must
|
||||
* be of concept output iterator.
|
||||
*/
|
||||
template<typename OutputIt>
|
||||
void copy(Py::Dict sourceRange, OutputIt targetIt)
|
||||
{
|
||||
string key;
|
||||
string value;
|
||||
|
||||
for (auto keyPy : sourceRange.keys()) {
|
||||
key = Py::String(keyPy);
|
||||
value = Py::String(sourceRange[keyPy]);
|
||||
*targetIt = {key, value};
|
||||
++targetIt;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class Module : public Py::ExtensionModule<Module>
|
||||
{
|
||||
public:
|
||||
@@ -133,6 +170,26 @@ public:
|
||||
add_varargs_method("makeGeomHatch",&Module::makeGeomHatch,
|
||||
"makeGeomHatch(face, [patScale], [patName], [patFile]) -- draw a geom hatch on a given face, using optionally the given scale (default 1) and a given pattern name (ex. Diamond) and .pat file (the default pattern name and/or .pat files set in preferences are used if none are given). Returns a Part compound shape."
|
||||
);
|
||||
add_varargs_method("project",&Module::project,
|
||||
"[visiblyG0,visiblyG1,hiddenG0,hiddenG1] = project(TopoShape[,App.Vector Direction, string type])\n"
|
||||
" -- Project a shape and return the visible/invisible parts of it."
|
||||
);
|
||||
add_varargs_method("projectEx",&Module::projectEx,
|
||||
"[V,V1,VN,VO,VI,H,H1,HN,HO,HI] = projectEx(TopoShape[,App.Vector Direction, string type])\n"
|
||||
" -- Project a shape and return the all parts of it."
|
||||
);
|
||||
add_keyword_method("projectToSVG",&Module::projectToSVG,
|
||||
"string = projectToSVG(TopoShape[, App.Vector direction, string type, float tolerance, dict vStyle, dict v0Style, dict v1Style, dict hStyle, dict h0Style, dict h1Style])\n"
|
||||
" -- Project a shape and return the SVG representation as string."
|
||||
);
|
||||
add_varargs_method("projectToDXF",&Module::projectToDXF,
|
||||
"string = projectToDXF(TopoShape[,App.Vector Direction, string type])\n"
|
||||
" -- Project a shape and return the DXF representation as string."
|
||||
);
|
||||
add_varargs_method("removeSvgTags",&Module::removeSvgTags,
|
||||
"string = removeSvgTags(string) -- Removes the opening and closing svg tags\n"
|
||||
"and other metatags from a svg code, making it embeddable"
|
||||
);
|
||||
initialize("This is a module for making drawings"); // register with Python
|
||||
}
|
||||
virtual ~Module() {}
|
||||
@@ -362,7 +419,7 @@ private:
|
||||
try {
|
||||
App::DocumentObject* obj = 0;
|
||||
TechDraw::DrawViewPart* dvp = 0;
|
||||
Drawing::DXFOutput dxfOut;
|
||||
TechDraw::DXFOutput dxfOut;
|
||||
std::string dxfText;
|
||||
std::stringstream ss;
|
||||
if (PyObject_TypeCheck(viewObj, &(TechDraw::DrawViewPartPy::Type))) {
|
||||
@@ -419,7 +476,7 @@ private:
|
||||
try {
|
||||
App::DocumentObject* obj = 0;
|
||||
TechDraw::DrawViewPart* dvp = 0;
|
||||
Drawing::SVGOutput svgOut;
|
||||
TechDraw::SVGOutput svgOut;
|
||||
std::string svgText;
|
||||
std::stringstream ss;
|
||||
if (PyObject_TypeCheck(viewObj, &(TechDraw::DrawViewPartPy::Type))) {
|
||||
@@ -965,6 +1022,192 @@ private:
|
||||
return Py::None();
|
||||
}
|
||||
|
||||
Py::Object project(const Py::Tuple& args)
|
||||
{
|
||||
PyObject *pcObjShape;
|
||||
PyObject *pcObjDir=0;
|
||||
|
||||
if (!PyArg_ParseTuple(args.ptr(), "O!|O!",
|
||||
&(Part::TopoShapePy::Type), &pcObjShape,
|
||||
&(Base::VectorPy::Type), &pcObjDir))
|
||||
throw Py::Exception();
|
||||
|
||||
Part::TopoShapePy* pShape = static_cast<Part::TopoShapePy*>(pcObjShape);
|
||||
Base::Vector3d Vector(0,0,1);
|
||||
if (pcObjDir)
|
||||
Vector = *static_cast<Base::VectorPy*>(pcObjDir)->getVectorPtr();
|
||||
|
||||
ProjectionAlgos Alg(pShape->getTopoShapePtr()->getShape(),Vector);
|
||||
|
||||
Py::List list;
|
||||
list.append(Py::Object(new Part::TopoShapePy(new Part::TopoShape(Alg.V)) , true));
|
||||
list.append(Py::Object(new Part::TopoShapePy(new Part::TopoShape(Alg.V1)), true));
|
||||
list.append(Py::Object(new Part::TopoShapePy(new Part::TopoShape(Alg.H)) , true));
|
||||
list.append(Py::Object(new Part::TopoShapePy(new Part::TopoShape(Alg.H1)), true));
|
||||
|
||||
return list;
|
||||
}
|
||||
Py::Object projectEx(const Py::Tuple& args)
|
||||
{
|
||||
PyObject *pcObjShape;
|
||||
PyObject *pcObjDir=0;
|
||||
|
||||
if (!PyArg_ParseTuple(args.ptr(), "O!|O!",
|
||||
&(TopoShapePy::Type), &pcObjShape,
|
||||
&(Base::VectorPy::Type), &pcObjDir))
|
||||
throw Py::Exception();
|
||||
|
||||
TopoShapePy* pShape = static_cast<TopoShapePy*>(pcObjShape);
|
||||
Base::Vector3d Vector(0,0,1);
|
||||
if (pcObjDir)
|
||||
Vector = *static_cast<Base::VectorPy*>(pcObjDir)->getVectorPtr();
|
||||
|
||||
ProjectionAlgos Alg(pShape->getTopoShapePtr()->getShape(),Vector);
|
||||
|
||||
Py::List list;
|
||||
list.append(Py::Object(new TopoShapePy(new TopoShape(Alg.V)) , true));
|
||||
list.append(Py::Object(new TopoShapePy(new TopoShape(Alg.V1)), true));
|
||||
list.append(Py::Object(new TopoShapePy(new TopoShape(Alg.VN)), true));
|
||||
list.append(Py::Object(new TopoShapePy(new TopoShape(Alg.VO)), true));
|
||||
list.append(Py::Object(new TopoShapePy(new TopoShape(Alg.VI)), true));
|
||||
list.append(Py::Object(new TopoShapePy(new TopoShape(Alg.H)) , true));
|
||||
list.append(Py::Object(new TopoShapePy(new TopoShape(Alg.H1)), true));
|
||||
list.append(Py::Object(new TopoShapePy(new TopoShape(Alg.HN)), true));
|
||||
list.append(Py::Object(new TopoShapePy(new TopoShape(Alg.HO)), true));
|
||||
list.append(Py::Object(new TopoShapePy(new TopoShape(Alg.HI)), true));
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
Py::Object projectToSVG(const Py::Tuple& args, const Py::Dict& keys)
|
||||
{
|
||||
static char* argNames[] = {"topoShape", "direction", "type", "tolerance", "vStyle", "v0Style", "v1Style", "hStyle", "h0Style", "h1Style", NULL};
|
||||
PyObject *pcObjShape = 0;
|
||||
PyObject *pcObjDir = 0;
|
||||
const char *extractionTypePy = 0;
|
||||
ProjectionAlgos::ExtractionType extractionType = ProjectionAlgos::Plain;
|
||||
const float tol = 0.1f;
|
||||
PyObject* vStylePy = 0;
|
||||
ProjectionAlgos::XmlAttributes vStyle;
|
||||
PyObject* v0StylePy = 0;
|
||||
ProjectionAlgos::XmlAttributes v0Style;
|
||||
PyObject* v1StylePy = 0;
|
||||
ProjectionAlgos::XmlAttributes v1Style;
|
||||
PyObject* hStylePy = 0;
|
||||
ProjectionAlgos::XmlAttributes hStyle;
|
||||
PyObject* h0StylePy = 0;
|
||||
ProjectionAlgos::XmlAttributes h0Style;
|
||||
PyObject* h1StylePy = 0;
|
||||
ProjectionAlgos::XmlAttributes h1Style;
|
||||
|
||||
// Get the arguments
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(
|
||||
args.ptr(), keys.ptr(),
|
||||
"O!|O!sfOOOOOO",
|
||||
argNames,
|
||||
&(TopoShapePy::Type), &pcObjShape,
|
||||
&(Base::VectorPy::Type), &pcObjDir,
|
||||
&extractionTypePy, &tol,
|
||||
&vStylePy, &v0StylePy, &v1StylePy,
|
||||
&hStylePy, &h0StylePy, &h1StylePy))
|
||||
|
||||
throw Py::Exception();
|
||||
|
||||
// Convert all arguments into the right format
|
||||
|
||||
TopoShapePy* pShape = static_cast<TopoShapePy*>(pcObjShape);
|
||||
|
||||
Base::Vector3d directionVector(0,0,1);
|
||||
if (pcObjDir)
|
||||
directionVector = static_cast<Base::VectorPy*>(pcObjDir)->value();
|
||||
|
||||
if (extractionTypePy && std::string(extractionTypePy) == "ShowHiddenLines")
|
||||
extractionType = ProjectionAlgos::WithHidden;
|
||||
|
||||
if (vStylePy)
|
||||
copy(Py::Dict(vStylePy), inserter(vStyle, vStyle.begin()));
|
||||
if (v0StylePy)
|
||||
copy(Py::Dict(v0StylePy), inserter(v0Style, v0Style.begin()));
|
||||
if (v1StylePy)
|
||||
copy(Py::Dict(v1StylePy), inserter(v1Style, v1Style.begin()));
|
||||
if (hStylePy)
|
||||
copy(Py::Dict(hStylePy), inserter(hStyle, hStyle.begin()));
|
||||
if (h0StylePy)
|
||||
copy(Py::Dict(h0StylePy), inserter(h0Style, h0Style.begin()));
|
||||
if (h1StylePy)
|
||||
copy(Py::Dict(h1StylePy), inserter(h1Style, h1Style.begin()));
|
||||
|
||||
// Execute the SVG generation
|
||||
|
||||
ProjectionAlgos Alg(pShape->getTopoShapePtr()->getShape(),
|
||||
directionVector);
|
||||
Py::String result(Alg.getSVG(extractionType, tol,
|
||||
vStyle, v0Style, v1Style,
|
||||
hStyle, h0Style, h1Style));
|
||||
return result;
|
||||
}
|
||||
|
||||
Py::Object projectToDXF(const Py::Tuple& args)
|
||||
{
|
||||
PyObject *pcObjShape;
|
||||
PyObject *pcObjDir=0;
|
||||
const char *type=0;
|
||||
float scale=1.0f;
|
||||
float tol=0.1f;
|
||||
|
||||
if (!PyArg_ParseTuple(args.ptr(), "O!|O!sff",
|
||||
&(TopoShapePy::Type), &pcObjShape,
|
||||
&(Base::VectorPy::Type), &pcObjDir, &type, &scale, &tol))
|
||||
throw Py::Exception();
|
||||
|
||||
TopoShapePy* pShape = static_cast<TopoShapePy*>(pcObjShape);
|
||||
Base::Vector3d Vector(0,0,1);
|
||||
if (pcObjDir)
|
||||
Vector = static_cast<Base::VectorPy*>(pcObjDir)->value();
|
||||
ProjectionAlgos Alg(pShape->getTopoShapePtr()->getShape(),Vector);
|
||||
|
||||
bool hidden = false;
|
||||
if (type && std::string(type) == "ShowHiddenLines")
|
||||
hidden = true;
|
||||
|
||||
Py::String result(Alg.getDXF(hidden?ProjectionAlgos::WithHidden:ProjectionAlgos::Plain, scale, tol));
|
||||
return result;
|
||||
}
|
||||
Py::Object removeSvgTags(const Py::Tuple& args)
|
||||
{
|
||||
const char* svgcode;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "s",&svgcode))
|
||||
throw Py::Exception();
|
||||
|
||||
std::string svg(svgcode);
|
||||
std::string empty = "";
|
||||
std::string endline = "--endOfLine--";
|
||||
std::string linebreak = "\\n";
|
||||
// removing linebreaks for regex to work
|
||||
boost::regex e1 ("\\n");
|
||||
svg = boost::regex_replace(svg, e1, endline);
|
||||
// removing starting xml definition
|
||||
boost::regex e2 ("<\\?xml.*?\\?>");
|
||||
svg = boost::regex_replace(svg, e2, empty);
|
||||
// removing starting svg tag
|
||||
boost::regex e3 ("<svg.*?>");
|
||||
svg = boost::regex_replace(svg, e3, empty);
|
||||
// removing sodipodi tags -- DANGEROUS, some sodipodi tags are single, better leave it
|
||||
//boost::regex e4 ("<sodipodi.*?>");
|
||||
//svg = boost::regex_replace(svg, e4, empty);
|
||||
// removing metadata tags
|
||||
boost::regex e5 ("<metadata.*?</metadata>");
|
||||
svg = boost::regex_replace(svg, e5, empty);
|
||||
// removing closing svg tags
|
||||
boost::regex e6 ("</svg>");
|
||||
svg = boost::regex_replace(svg, e6, empty);
|
||||
// restoring linebreaks
|
||||
boost::regex e7 ("--endOfLine--");
|
||||
svg = boost::regex_replace(svg, e7, linebreak);
|
||||
Py::String result(svg);
|
||||
return result;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -132,6 +132,8 @@ SET(Draw_SRCS
|
||||
DrawTileWeld.h
|
||||
DrawWeldSymbol.cpp
|
||||
DrawWeldSymbol.h
|
||||
FeatureProjection.cpp
|
||||
FeatureProjection.h
|
||||
)
|
||||
|
||||
SET(TechDraw_SRCS
|
||||
@@ -157,6 +159,10 @@ SET(TechDraw_SRCS
|
||||
ArrowPropEnum.h
|
||||
Preferences.cpp
|
||||
Preferences.h
|
||||
TechDrawExport.cpp
|
||||
TechDrawExport.h
|
||||
ProjectionAlgos.cpp
|
||||
ProjectionAlgos.h
|
||||
)
|
||||
|
||||
SET(Geometry_SRCS
|
||||
|
||||
116
src/Mod/TechDraw/App/FeatureProjection.cpp
Normal file
116
src/Mod/TechDraw/App/FeatureProjection.cpp
Normal file
@@ -0,0 +1,116 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2009 Werner Mayer <wmayer[at]users.sourceforge.net> *
|
||||
* *
|
||||
* 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 *
|
||||
* *
|
||||
***************************************************************************/
|
||||
//this file originally part of TechDraw workbench
|
||||
//migrated to TechDraw workbench 2022-01-26 by Wandererfan
|
||||
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
# include <sstream>
|
||||
# include <BRep_Builder.hxx>
|
||||
# include <Standard_Failure.hxx>
|
||||
# include <TopoDS_Compound.hxx>
|
||||
#endif
|
||||
|
||||
|
||||
#include <Base/Writer.h>
|
||||
#include <Base/Reader.h>
|
||||
#include <Base/Exception.h>
|
||||
#include <Base/FileInfo.h>
|
||||
|
||||
#include "FeatureProjection.h"
|
||||
#include "ProjectionAlgos.h"
|
||||
|
||||
using namespace TechDraw;
|
||||
|
||||
|
||||
PROPERTY_SOURCE(TechDraw::FeatureProjection, Part::Feature)
|
||||
|
||||
|
||||
FeatureProjection::FeatureProjection()
|
||||
{
|
||||
static const char *group = "Projection";
|
||||
ADD_PROPERTY_TYPE(Source ,(0),group,App::Prop_None,"Shape to project");
|
||||
ADD_PROPERTY_TYPE(Direction ,(Base::Vector3d(0,0,1)),group,App::Prop_None,"Projection direction");
|
||||
ADD_PROPERTY_TYPE(VCompound ,(true),group,App::Prop_None,"Projection parameter");
|
||||
ADD_PROPERTY_TYPE(Rg1LineVCompound ,(true),group,App::Prop_None,"Projection parameter");
|
||||
ADD_PROPERTY_TYPE(RgNLineVCompound ,(true),group,App::Prop_None,"Projection parameter");
|
||||
ADD_PROPERTY_TYPE(OutLineVCompound ,(true),group,App::Prop_None,"Projection parameter");
|
||||
ADD_PROPERTY_TYPE(IsoLineVCompound ,(true),group,App::Prop_None,"Projection parameter");
|
||||
ADD_PROPERTY_TYPE(HCompound ,(true),group,App::Prop_None,"Projection parameter");
|
||||
ADD_PROPERTY_TYPE(Rg1LineHCompound ,(true),group,App::Prop_None,"Projection parameter");
|
||||
ADD_PROPERTY_TYPE(RgNLineHCompound ,(true),group,App::Prop_None,"Projection parameter");
|
||||
ADD_PROPERTY_TYPE(OutLineHCompound ,(true),group,App::Prop_None,"Projection parameter");
|
||||
ADD_PROPERTY_TYPE(IsoLineHCompound ,(true),group,App::Prop_None,"Projection parameter");
|
||||
}
|
||||
|
||||
FeatureProjection::~FeatureProjection()
|
||||
{
|
||||
}
|
||||
|
||||
App::DocumentObjectExecReturn *FeatureProjection::execute(void)
|
||||
{
|
||||
App::DocumentObject* link = Source.getValue();
|
||||
if (!link)
|
||||
return new App::DocumentObjectExecReturn("No object linked");
|
||||
if (!link->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId()))
|
||||
return new App::DocumentObjectExecReturn("Linked object is not a Part object");
|
||||
const TopoDS_Shape& shape = static_cast<Part::Feature*>(link)->Shape.getShape().getShape();
|
||||
if (shape.IsNull())
|
||||
return new App::DocumentObjectExecReturn("Linked shape object is empty");
|
||||
|
||||
try {
|
||||
const Base::Vector3d& dir = Direction.getValue();
|
||||
TechDraw::ProjectionAlgos alg(shape, dir);
|
||||
|
||||
TopoDS_Compound comp;
|
||||
BRep_Builder builder;
|
||||
builder.MakeCompound(comp);
|
||||
if (!alg.V.IsNull() && VCompound.getValue())
|
||||
builder.Add(comp, alg.V);
|
||||
if (!alg.V1.IsNull() && Rg1LineVCompound.getValue())
|
||||
builder.Add(comp, alg.V1);
|
||||
if (!alg.VN.IsNull() && RgNLineVCompound.getValue())
|
||||
builder.Add(comp, alg.VN);
|
||||
if (!alg.VO.IsNull() && OutLineVCompound.getValue())
|
||||
builder.Add(comp, alg.VO);
|
||||
if (!alg.VI.IsNull() && IsoLineVCompound.getValue())
|
||||
builder.Add(comp, alg.VI);
|
||||
if (!alg.H.IsNull() && HCompound.getValue())
|
||||
builder.Add(comp, alg.H);
|
||||
if (!alg.H1.IsNull() && Rg1LineHCompound.getValue())
|
||||
builder.Add(comp, alg.H1);
|
||||
if (!alg.HN.IsNull() && RgNLineHCompound.getValue())
|
||||
builder.Add(comp, alg.HN);
|
||||
if (!alg.HO.IsNull() && OutLineHCompound.getValue())
|
||||
builder.Add(comp, alg.HO);
|
||||
if (!alg.HI.IsNull() && IsoLineHCompound.getValue())
|
||||
builder.Add(comp, alg.HI);
|
||||
|
||||
Shape.setValue(comp);
|
||||
return App::DocumentObject::StdReturn;
|
||||
}
|
||||
catch (Standard_Failure& e) {
|
||||
return new App::DocumentObjectExecReturn(e.GetMessageString());
|
||||
}
|
||||
}
|
||||
75
src/Mod/TechDraw/App/FeatureProjection.h
Normal file
75
src/Mod/TechDraw/App/FeatureProjection.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2009 Werner Mayer <wmayer[at]users.sourceforge.net> *
|
||||
* *
|
||||
* 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 *
|
||||
* *
|
||||
***************************************************************************/
|
||||
//this file originally part of TechDraw workbench
|
||||
//migrated to TechDraw workbench 2022-01-26 by Wandererfan
|
||||
|
||||
|
||||
#ifndef TECHDRAW_FEATUREPROJECTION
|
||||
#define TECHDRAW_FEATUREPROJECTION
|
||||
|
||||
|
||||
#include <App/DocumentObject.h>
|
||||
#include <App/PropertyStandard.h>
|
||||
#include <App/PropertyGeo.h>
|
||||
#include <Mod/Part/App/PartFeature.h>
|
||||
|
||||
|
||||
namespace TechDraw
|
||||
{
|
||||
|
||||
|
||||
/** Base class of all View Features in the drawing module
|
||||
*/
|
||||
class TechDrawExport FeatureProjection : public Part::Feature
|
||||
{
|
||||
PROPERTY_HEADER(TechDraw::FeatureProjection);
|
||||
|
||||
public:
|
||||
/// Constructor
|
||||
FeatureProjection();
|
||||
virtual ~FeatureProjection();
|
||||
|
||||
App::PropertyLink Source;
|
||||
App::PropertyVector Direction;
|
||||
App::PropertyBool VCompound;
|
||||
App::PropertyBool Rg1LineVCompound;
|
||||
App::PropertyBool RgNLineVCompound;
|
||||
App::PropertyBool OutLineVCompound;
|
||||
App::PropertyBool IsoLineVCompound;
|
||||
App::PropertyBool HCompound;
|
||||
App::PropertyBool Rg1LineHCompound;
|
||||
App::PropertyBool RgNLineHCompound;
|
||||
App::PropertyBool OutLineHCompound;
|
||||
App::PropertyBool IsoLineHCompound;
|
||||
|
||||
/** @name methods override feature */
|
||||
//@{
|
||||
/// recalculate the Feature
|
||||
virtual App::DocumentObjectExecReturn *execute(void);
|
||||
//@}
|
||||
};
|
||||
|
||||
} //namespace TechDraw
|
||||
|
||||
|
||||
|
||||
#endif // TECHDRAW_FEATUREPROJECTION
|
||||
290
src/Mod/TechDraw/App/ProjectionAlgos.cpp
Normal file
290
src/Mod/TechDraw/App/ProjectionAlgos.cpp
Normal file
@@ -0,0 +1,290 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) Jürgen Riegel (juergen.riegel@web.de) 2002 *
|
||||
* *
|
||||
* 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 *
|
||||
* *
|
||||
***************************************************************************/
|
||||
//this file originally part of TechDraw workbench
|
||||
//migrated to TechDraw workbench 2022-01-26 by Wandererfan
|
||||
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
# include <sstream>
|
||||
# include <BRepAdaptor_Curve.hxx>
|
||||
# include <Geom_Circle.hxx>
|
||||
# include <gp_Circ.hxx>
|
||||
# include <gp_Elips.hxx>
|
||||
#endif
|
||||
|
||||
#include <Bnd_Box.hxx>
|
||||
#include <BRepBndLib.hxx>
|
||||
#include <BRepBuilderAPI_Transform.hxx>
|
||||
#include <HLRBRep_Algo.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <HLRTopoBRep_OutLiner.hxx>
|
||||
#include <HLRAlgo_Projector.hxx>
|
||||
#include <HLRBRep_ShapeBounds.hxx>
|
||||
#include <HLRBRep_HLRToShape.hxx>
|
||||
#include <gp_Ax2.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Dir.hxx>
|
||||
#include <gp_Vec.hxx>
|
||||
#include <Poly_Polygon3D.hxx>
|
||||
#include <Poly_Triangulation.hxx>
|
||||
#include <Poly_PolygonOnTriangulation.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
#include <TopExp.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
#include <TopTools_IndexedMapOfShape.hxx>
|
||||
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
|
||||
#include <TopTools_ListOfShape.hxx>
|
||||
#include <TColgp_Array1OfPnt2d.hxx>
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <BRepMesh_IncrementalMesh.hxx>
|
||||
#include <BRepLib.hxx>
|
||||
#include <BRepAdaptor_CompCurve.hxx>
|
||||
#include <Approx_Curve3d.hxx>
|
||||
#include <Geom_BSplineCurve.hxx>
|
||||
#include <Geom_BezierCurve.hxx>
|
||||
#include <GeomConvert_BSplineCurveToBezierCurve.hxx>
|
||||
#include <GeomConvert_BSplineCurveKnotSplitting.hxx>
|
||||
#include <Geom2d_BSplineCurve.hxx>
|
||||
|
||||
#include <Base/Exception.h>
|
||||
#include <Base/FileInfo.h>
|
||||
#include <Base/Tools.h>
|
||||
#include <Mod/Part/App/PartFeature.h>
|
||||
|
||||
#include "ProjectionAlgos.h"
|
||||
#include "TechDrawExport.h"
|
||||
|
||||
using namespace TechDraw;
|
||||
using namespace std;
|
||||
|
||||
//===========================================================================
|
||||
// ProjectionAlgos
|
||||
//===========================================================================
|
||||
|
||||
|
||||
|
||||
ProjectionAlgos::ProjectionAlgos(const TopoDS_Shape &Input, const Base::Vector3d &Dir)
|
||||
: Input(Input), Direction(Dir)
|
||||
{
|
||||
execute();
|
||||
}
|
||||
|
||||
ProjectionAlgos::~ProjectionAlgos()
|
||||
{
|
||||
}
|
||||
|
||||
//added by tanderson. aka blobfish.
|
||||
//projection algorithms build a 2d curve(pcurve) but no 3d curve.
|
||||
//this causes problems with meshing algorithms after save and load.
|
||||
static const TopoDS_Shape& build3dCurves(const TopoDS_Shape &shape)
|
||||
{
|
||||
TopExp_Explorer it;
|
||||
for (it.Init(shape, TopAbs_EDGE); it.More(); it.Next())
|
||||
BRepLib::BuildCurve3d(TopoDS::Edge(it.Current()));
|
||||
return shape;
|
||||
}
|
||||
|
||||
void ProjectionAlgos::execute(void)
|
||||
{
|
||||
Handle( HLRBRep_Algo ) brep_hlr = new HLRBRep_Algo;
|
||||
brep_hlr->Add(Input);
|
||||
|
||||
gp_Ax2 transform(gp_Pnt(0,0,0),gp_Dir(Direction.x,Direction.y,Direction.z));
|
||||
HLRAlgo_Projector projector( transform );
|
||||
brep_hlr->Projector(projector);
|
||||
brep_hlr->Update();
|
||||
brep_hlr->Hide();
|
||||
|
||||
// extracting the result sets:
|
||||
HLRBRep_HLRToShape shapes( brep_hlr );
|
||||
|
||||
V = build3dCurves(shapes.VCompound ());// hard edge visibly
|
||||
V1 = build3dCurves(shapes.Rg1LineVCompound());// Smoth edges visibly
|
||||
VN = build3dCurves(shapes.RgNLineVCompound());// contour edges visibly
|
||||
VO = build3dCurves(shapes.OutLineVCompound());// contours apparents visibly
|
||||
VI = build3dCurves(shapes.IsoLineVCompound());// isoparamtriques visibly
|
||||
H = build3dCurves(shapes.HCompound ());// hard edge invisibly
|
||||
H1 = build3dCurves(shapes.Rg1LineHCompound());// Smoth edges invisibly
|
||||
HN = build3dCurves(shapes.RgNLineHCompound());// contour edges invisibly
|
||||
HO = build3dCurves(shapes.OutLineHCompound());// contours apparents invisibly
|
||||
HI = build3dCurves(shapes.IsoLineHCompound());// isoparamtriques invisibly
|
||||
}
|
||||
|
||||
string ProjectionAlgos::getSVG(ExtractionType type,
|
||||
double tolerance,
|
||||
XmlAttributes V_style,
|
||||
XmlAttributes V0_style,
|
||||
XmlAttributes V1_style,
|
||||
XmlAttributes H_style,
|
||||
XmlAttributes H0_style,
|
||||
XmlAttributes H1_style)
|
||||
{
|
||||
stringstream result;
|
||||
SVGOutput output;
|
||||
|
||||
if (!H.IsNull() && (type & WithHidden)) {
|
||||
H_style.insert({"stroke", "rgb(0, 0, 0)"});
|
||||
H_style.insert({"stroke-width", "0.15"});
|
||||
H_style.insert({"stroke-linecap", "butt"});
|
||||
H_style.insert({"stroke-linejoin", "miter"});
|
||||
H_style.insert({"stroke-dasharray", "0.2,0.1)"});
|
||||
H_style.insert({"fill", "none"});
|
||||
H_style.insert({"transform", "scale(1,-1)"});
|
||||
BRepMesh_IncrementalMesh(H,tolerance);
|
||||
result << "<g";
|
||||
for (const auto& attribute : H_style)
|
||||
result << " " << attribute.first << "=\""
|
||||
<< attribute.second << "\"\n";
|
||||
result << " >" << endl
|
||||
<< output.exportEdges(H)
|
||||
<< "</g>" << endl;
|
||||
}
|
||||
if (!HO.IsNull() && (type & WithHidden)) {
|
||||
H0_style.insert({"stroke", "rgb(0, 0, 0)"});
|
||||
H0_style.insert({"stroke-width", "0.15"});
|
||||
H0_style.insert({"stroke-linecap", "butt"});
|
||||
H0_style.insert({"stroke-linejoin", "miter"});
|
||||
H0_style.insert({"stroke-dasharray", "0.02,0.1)"});
|
||||
H0_style.insert({"fill", "none"});
|
||||
H0_style.insert({"transform", "scale(1,-1)"});
|
||||
BRepMesh_IncrementalMesh(HO,tolerance);
|
||||
result << "<g";
|
||||
for (const auto& attribute : H0_style)
|
||||
result << " " << attribute.first << "=\""
|
||||
<< attribute.second << "\"\n";
|
||||
result << " >" << endl
|
||||
<< output.exportEdges(HO)
|
||||
<< "</g>" << endl;
|
||||
}
|
||||
if (!VO.IsNull()) {
|
||||
V0_style.insert({"stroke", "rgb(0, 0, 0)"});
|
||||
V0_style.insert({"stroke-width", "1.0"});
|
||||
V0_style.insert({"stroke-linecap", "butt"});
|
||||
V0_style.insert({"stroke-linejoin", "miter"});
|
||||
V0_style.insert({"fill", "none"});
|
||||
V0_style.insert({"transform", "scale(1,-1)"});
|
||||
BRepMesh_IncrementalMesh(VO,tolerance);
|
||||
result << "<g";
|
||||
for (const auto& attribute : V0_style)
|
||||
result << " " << attribute.first << "=\""
|
||||
<< attribute.second << "\"\n";
|
||||
result << " >" << endl
|
||||
<< output.exportEdges(VO)
|
||||
<< "</g>" << endl;
|
||||
}
|
||||
if (!V.IsNull()) {
|
||||
V_style.insert({"stroke", "rgb(0, 0, 0)"});
|
||||
V_style.insert({"stroke-width", "1.0"});
|
||||
V_style.insert({"stroke-linecap", "butt"});
|
||||
V_style.insert({"stroke-linejoin", "miter"});
|
||||
V_style.insert({"fill", "none"});
|
||||
V_style.insert({"transform", "scale(1,-1)"});
|
||||
BRepMesh_IncrementalMesh(V,tolerance);
|
||||
result << "<g";
|
||||
for (const auto& attribute : V_style)
|
||||
result << " " << attribute.first << "=\""
|
||||
<< attribute.second << "\"\n";
|
||||
result << " >" << endl
|
||||
<< output.exportEdges(V)
|
||||
<< "</g>" << endl;
|
||||
}
|
||||
if (!V1.IsNull() && (type & WithSmooth)) {
|
||||
V1_style.insert({"stroke", "rgb(0, 0, 0)"});
|
||||
V1_style.insert({"stroke-width", "1.0"});
|
||||
V1_style.insert({"stroke-linecap", "butt"});
|
||||
V1_style.insert({"stroke-linejoin", "miter"});
|
||||
V1_style.insert({"fill", "none"});
|
||||
V1_style.insert({"transform", "scale(1,-1)"});
|
||||
BRepMesh_IncrementalMesh(V1,tolerance);
|
||||
result << "<g";
|
||||
for (const auto& attribute : V1_style)
|
||||
result << " " << attribute.first << "=\""
|
||||
<< attribute.second << "\"\n";
|
||||
result << " >" << endl
|
||||
<< output.exportEdges(V1)
|
||||
<< "</g>" << endl;
|
||||
}
|
||||
if (!H1.IsNull() && (type & WithSmooth) && (type & WithHidden)) {
|
||||
H1_style.insert({"stroke", "rgb(0, 0, 0)"});
|
||||
H1_style.insert({"stroke-width", "0.15"});
|
||||
H1_style.insert({"stroke-linecap", "butt"});
|
||||
H1_style.insert({"stroke-linejoin", "miter"});
|
||||
H1_style.insert({"stroke-dasharray", "0.09,0.05)"});
|
||||
H1_style.insert({"fill", "none"});
|
||||
H1_style.insert({"transform", "scale(1,-1)"});
|
||||
BRepMesh_IncrementalMesh(H1,tolerance);
|
||||
result << "<g";
|
||||
for (const auto& attribute : H1_style)
|
||||
result << " " << attribute.first << "=\""
|
||||
<< attribute.second << "\"\n";
|
||||
result << " >" << endl
|
||||
<< output.exportEdges(H1)
|
||||
<< "</g>" << endl;
|
||||
}
|
||||
return result.str();
|
||||
}
|
||||
|
||||
/* dxf output section - Dan Falck 2011/09/25 */
|
||||
|
||||
string ProjectionAlgos::getDXF(ExtractionType type, double /*scale*/, double tolerance)
|
||||
{
|
||||
stringstream result;
|
||||
DXFOutput output;
|
||||
|
||||
if (!H.IsNull() && (type & WithHidden)) {
|
||||
//float width = 0.15f/scale;
|
||||
BRepMesh_IncrementalMesh(H,tolerance);
|
||||
result << output.exportEdges(H);
|
||||
}
|
||||
if (!HO.IsNull() && (type & WithHidden)) {
|
||||
//float width = 0.15f/scale;
|
||||
BRepMesh_IncrementalMesh(HO,tolerance);
|
||||
result << output.exportEdges(HO);
|
||||
}
|
||||
if (!VO.IsNull()) {
|
||||
//float width = 0.35f/scale;
|
||||
BRepMesh_IncrementalMesh(VO,tolerance);
|
||||
result << output.exportEdges(VO);
|
||||
}
|
||||
if (!V.IsNull()) {
|
||||
//float width = 0.35f/scale;
|
||||
BRepMesh_IncrementalMesh(V,tolerance);
|
||||
result << output.exportEdges(V);
|
||||
}
|
||||
if (!V1.IsNull() && (type & WithSmooth)) {
|
||||
//float width = 0.35f/scale;
|
||||
BRepMesh_IncrementalMesh(V1,tolerance);
|
||||
result << output.exportEdges(V1);
|
||||
}
|
||||
if (!H1.IsNull() && (type & WithSmooth) && (type & WithHidden)) {
|
||||
//float width = 0.15f/scale;
|
||||
BRepMesh_IncrementalMesh(H1,tolerance);
|
||||
result << output.exportEdges(H1);
|
||||
}
|
||||
|
||||
return result.str();
|
||||
}
|
||||
86
src/Mod/TechDraw/App/ProjectionAlgos.h
Normal file
86
src/Mod/TechDraw/App/ProjectionAlgos.h
Normal file
@@ -0,0 +1,86 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) Jürgen Riegel (juergen.riegel@web.de) 2009 *
|
||||
* *
|
||||
* 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 *
|
||||
* *
|
||||
***************************************************************************/
|
||||
//this file originally part of TechDraw workbench
|
||||
//migrated to TechDraw workbench 2022-01-26 by Wandererfan
|
||||
|
||||
|
||||
#ifndef _TechDrawProjectionAlgos_h_
|
||||
#define _TechDrawProjectionAlgos_h_
|
||||
|
||||
#include <Mod/TechDraw/TechDrawGlobal.h>
|
||||
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <Base/Vector3D.h>
|
||||
#include <string>
|
||||
|
||||
class BRepAdaptor_Curve;
|
||||
|
||||
namespace TechDraw
|
||||
{
|
||||
|
||||
/** Algo class for projecting shapes and creating SVG output of it
|
||||
*/
|
||||
class TechDrawExport ProjectionAlgos
|
||||
{
|
||||
public:
|
||||
/// Constructor
|
||||
ProjectionAlgos(const TopoDS_Shape &Input,const Base::Vector3d &Dir);
|
||||
virtual ~ProjectionAlgos();
|
||||
|
||||
void execute(void);
|
||||
|
||||
enum ExtractionType {
|
||||
Plain = 0,
|
||||
WithHidden = 1,
|
||||
WithSmooth = 2
|
||||
};
|
||||
typedef std::map<std::string,std::string> XmlAttributes;
|
||||
|
||||
std::string getSVG(ExtractionType type, double tolerance=0.05,
|
||||
XmlAttributes V_style=XmlAttributes(),
|
||||
XmlAttributes V0_style=XmlAttributes(),
|
||||
XmlAttributes V1_style=XmlAttributes(),
|
||||
XmlAttributes H_style=XmlAttributes(),
|
||||
XmlAttributes H0_style=XmlAttributes(),
|
||||
XmlAttributes H1_style=XmlAttributes());
|
||||
std::string getDXF(ExtractionType type, double scale, double tolerance);//added by Dan Falck 2011/09/25
|
||||
|
||||
|
||||
const TopoDS_Shape &Input;
|
||||
const Base::Vector3d &Direction;
|
||||
|
||||
TopoDS_Shape V ;// hard edge visibly
|
||||
TopoDS_Shape V1;// Smoth edges visibly
|
||||
TopoDS_Shape VN;// contour edges visibly
|
||||
TopoDS_Shape VO;// contours apparents visibly
|
||||
TopoDS_Shape VI;// isoparamtriques visibly
|
||||
TopoDS_Shape H ;// hard edge invisibly
|
||||
TopoDS_Shape H1;// Smoth edges invisibly
|
||||
TopoDS_Shape HN;// contour edges invisibly
|
||||
TopoDS_Shape HO;// contours apparents invisibly
|
||||
TopoDS_Shape HI;// isoparamtriques invisibly
|
||||
};
|
||||
|
||||
} //namespace TechDraw
|
||||
|
||||
|
||||
#endif
|
||||
771
src/Mod/TechDraw/App/TechDrawExport.cpp
Normal file
771
src/Mod/TechDraw/App/TechDrawExport.cpp
Normal file
@@ -0,0 +1,771 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2011 Werner Mayer <wmayer[at]users.sourceforge.net> *
|
||||
* *
|
||||
* 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 *
|
||||
* *
|
||||
***************************************************************************/
|
||||
//this file originally part of TechDraw workbench
|
||||
//migrated to TechDraw workbench 2022-01-26 by Wandererfan
|
||||
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
# include <sstream>
|
||||
# include <cmath>
|
||||
# include <BRepAdaptor_Curve.hxx>
|
||||
# include <Geom_Circle.hxx>
|
||||
# include <gp_Circ.hxx>
|
||||
# include <gp_Elips.hxx>
|
||||
#endif
|
||||
|
||||
#include <Bnd_Box.hxx>
|
||||
#include <BRepBndLib.hxx>
|
||||
#include <BRepBuilderAPI_MakeEdge.hxx>
|
||||
#include <BRepBuilderAPI_Transform.hxx>
|
||||
#include <HLRBRep_Algo.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <HLRTopoBRep_OutLiner.hxx>
|
||||
//#include <BRepAPI_MakeOutLine.hxx>
|
||||
#include <HLRAlgo_Projector.hxx>
|
||||
#include <HLRBRep_ShapeBounds.hxx>
|
||||
#include <HLRBRep_HLRToShape.hxx>
|
||||
#include <gp_Ax2.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Dir.hxx>
|
||||
#include <gp_Vec.hxx>
|
||||
#include <Poly_Polygon3D.hxx>
|
||||
#include <Poly_Triangulation.hxx>
|
||||
#include <Poly_PolygonOnTriangulation.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
#include <TopExp.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
#include <TopTools_IndexedMapOfShape.hxx>
|
||||
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
|
||||
#include <TopTools_ListOfShape.hxx>
|
||||
#include <TColgp_Array1OfPnt2d.hxx>
|
||||
#include <TColStd_Array1OfReal.hxx>
|
||||
#include <BRep_Tool.hxx>
|
||||
|
||||
#include <BRepAdaptor_CompCurve.hxx>
|
||||
#include <Approx_Curve3d.hxx>
|
||||
#include <Geom_BSplineCurve.hxx>
|
||||
#include <Geom_BezierCurve.hxx>
|
||||
#include <GeomConvert_BSplineCurveToBezierCurve.hxx>
|
||||
#include <GeomConvert_BSplineCurveKnotSplitting.hxx>
|
||||
#include <Geom2d_BSplineCurve.hxx>
|
||||
#include <BRepLProp_CLProps.hxx>
|
||||
#include <Standard_Failure.hxx>
|
||||
#include <Standard_Version.hxx>
|
||||
#if OCC_VERSION_HEX < 0x070600
|
||||
#include <BRepAdaptor_HCurve.hxx>
|
||||
#endif
|
||||
|
||||
#include "TechDrawExport.h"
|
||||
#include <Base/Tools.h>
|
||||
#include <Base/Vector3D.h>
|
||||
|
||||
#if OCC_VERSION_HEX >= 0x070600
|
||||
using BRepAdaptor_HCurve = BRepAdaptor_Curve;
|
||||
#endif
|
||||
|
||||
using namespace TechDraw;
|
||||
using namespace std;
|
||||
|
||||
TopoDS_Edge TechDrawOutput::asCircle(const BRepAdaptor_Curve& c) const
|
||||
{
|
||||
double curv=0;
|
||||
gp_Pnt pnt, center;
|
||||
|
||||
try {
|
||||
// approximate the circle center from three positions
|
||||
BRepLProp_CLProps prop(c,c.FirstParameter(),2,Precision::Confusion());
|
||||
curv += prop.Curvature();
|
||||
prop.CentreOfCurvature(pnt);
|
||||
center.ChangeCoord().Add(pnt.Coord());
|
||||
|
||||
prop.SetParameter(0.5*(c.FirstParameter()+c.LastParameter()));
|
||||
curv += prop.Curvature();
|
||||
prop.CentreOfCurvature(pnt);
|
||||
center.ChangeCoord().Add(pnt.Coord());
|
||||
|
||||
prop.SetParameter(c.LastParameter());
|
||||
curv += prop.Curvature();
|
||||
prop.CentreOfCurvature(pnt);
|
||||
center.ChangeCoord().Add(pnt.Coord());
|
||||
|
||||
center.ChangeCoord().Divide(3);
|
||||
curv /= 3;
|
||||
}
|
||||
catch (Standard_Failure&) {
|
||||
// if getting center of curvature fails, e.g.
|
||||
// for straight lines it raises LProp_NotDefined
|
||||
return TopoDS_Edge();
|
||||
}
|
||||
|
||||
// get circle from curvature information
|
||||
double radius = 1 / curv;
|
||||
|
||||
TopLoc_Location location;
|
||||
Handle(Poly_Polygon3D) polygon = BRep_Tool::Polygon3D(c.Edge(), location);
|
||||
if (!polygon.IsNull()) {
|
||||
const TColgp_Array1OfPnt& nodes = polygon->Nodes();
|
||||
for (int i = nodes.Lower(); i <= nodes.Upper(); i++) {
|
||||
gp_Pnt p = nodes(i);
|
||||
double dist = p.Distance(center);
|
||||
if (std::abs(dist - radius) > 0.001)
|
||||
return TopoDS_Edge();
|
||||
}
|
||||
|
||||
gp_Circ circ;
|
||||
circ.SetLocation(center);
|
||||
circ.SetRadius(radius);
|
||||
gp_Pnt p1 = nodes(nodes.Lower());
|
||||
gp_Pnt p2 = nodes(nodes.Upper());
|
||||
double dist = p1.Distance(p2);
|
||||
|
||||
if (dist < Precision::Confusion()) {
|
||||
BRepBuilderAPI_MakeEdge mkEdge(circ);
|
||||
return mkEdge.Edge();
|
||||
}
|
||||
else {
|
||||
gp_Vec dir1(center, p1);
|
||||
dir1.Normalize();
|
||||
gp_Vec dir2(center, p2);
|
||||
dir2.Normalize();
|
||||
p1 = gp_Pnt(center.XYZ() + radius * dir1.XYZ());
|
||||
p2 = gp_Pnt(center.XYZ() + radius * dir2.XYZ());
|
||||
BRepBuilderAPI_MakeEdge mkEdge(circ, p1, p2);
|
||||
return mkEdge.Edge();
|
||||
}
|
||||
}
|
||||
|
||||
return TopoDS_Edge();
|
||||
}
|
||||
|
||||
TopoDS_Edge TechDrawOutput::asBSpline(const BRepAdaptor_Curve& c, int maxDegree) const
|
||||
{
|
||||
Standard_Real tol3D = 0.001;
|
||||
Standard_Integer maxSegment = 50;
|
||||
Handle(BRepAdaptor_HCurve) hCurve = new BRepAdaptor_HCurve(c);
|
||||
// approximate the curve using a tolerance
|
||||
Approx_Curve3d approx(hCurve,tol3D,GeomAbs_C0,maxSegment,maxDegree);
|
||||
if (approx.IsDone() && approx.HasResult()) {
|
||||
// have the result
|
||||
Handle(Geom_BSplineCurve) spline = approx.Curve();
|
||||
BRepBuilderAPI_MakeEdge mkEdge(spline, spline->FirstParameter(), spline->LastParameter());
|
||||
return mkEdge.Edge();
|
||||
}
|
||||
|
||||
return TopoDS_Edge();
|
||||
}
|
||||
|
||||
SVGOutput::SVGOutput()
|
||||
{
|
||||
}
|
||||
|
||||
std::string SVGOutput::exportEdges(const TopoDS_Shape& input)
|
||||
{
|
||||
std::stringstream result;
|
||||
|
||||
TopExp_Explorer edges(input, TopAbs_EDGE);
|
||||
for (int i = 1 ; edges.More(); edges.Next(),i++) {
|
||||
const TopoDS_Edge& edge = TopoDS::Edge(edges.Current());
|
||||
BRepAdaptor_Curve adapt(edge);
|
||||
if (adapt.GetType() == GeomAbs_Circle) {
|
||||
printCircle(adapt, result);
|
||||
}
|
||||
else if (adapt.GetType() == GeomAbs_Ellipse) {
|
||||
printEllipse(adapt, i, result);
|
||||
}
|
||||
else if (adapt.GetType() == GeomAbs_BSplineCurve) {
|
||||
// TopoDS_Edge circle = asCircle(adapt);
|
||||
// if (circle.IsNull()) {
|
||||
printBSpline(adapt, i, result);
|
||||
// }
|
||||
// else {
|
||||
// BRepAdaptor_Curve adapt_circle(circle);
|
||||
// printCircle(adapt_circle, result);
|
||||
// }
|
||||
}
|
||||
else if (adapt.GetType() == GeomAbs_BezierCurve) {
|
||||
printBezier(adapt, i, result);
|
||||
}
|
||||
// fallback
|
||||
else {
|
||||
printGeneric(adapt, i, result);
|
||||
}
|
||||
}
|
||||
|
||||
return result.str();
|
||||
}
|
||||
|
||||
void SVGOutput::printCircle(const BRepAdaptor_Curve& c, std::ostream& out)
|
||||
{
|
||||
gp_Circ circ = c.Circle();
|
||||
const gp_Pnt& p= circ.Location();
|
||||
double r = circ.Radius();
|
||||
double f = c.FirstParameter();
|
||||
double l = c.LastParameter();
|
||||
gp_Pnt s = c.Value(f);
|
||||
gp_Pnt m = c.Value((l+f)/2.0);
|
||||
gp_Pnt e = c.Value(l);
|
||||
|
||||
gp_Vec v1(m,s);
|
||||
gp_Vec v2(m,e);
|
||||
gp_Vec v3(0,0,1);
|
||||
double a = v3.DotCross(v1,v2);
|
||||
|
||||
// a full circle
|
||||
if (fabs(l-f) > 1.0 && s.SquareDistance(e) < 0.001) {
|
||||
out << "<circle cx =\"" << p.X() << "\" cy =\""
|
||||
<< p.Y() << "\" r =\"" << r << "\" />";
|
||||
}
|
||||
// arc of circle
|
||||
else {
|
||||
// See also https://developer.mozilla.org/en/SVG/Tutorial/Paths
|
||||
char xar = '0'; // x-axis-rotation
|
||||
char las = (l-f > D_PI) ? '1' : '0'; // large-arc-flag
|
||||
char swp = (a < 0) ? '1' : '0'; // sweep-flag, i.e. clockwise (0) or counter-clockwise (1)
|
||||
out << "<path d=\"M" << s.X() << " " << s.Y()
|
||||
<< " A" << r << " " << r << " "
|
||||
<< xar << " " << las << " " << swp << " "
|
||||
<< e.X() << " " << e.Y() << "\" />";
|
||||
}
|
||||
}
|
||||
|
||||
void SVGOutput::printEllipse(const BRepAdaptor_Curve& c, int id, std::ostream& out)
|
||||
{
|
||||
gp_Elips ellp = c.Ellipse();
|
||||
const gp_Pnt& p= ellp.Location();
|
||||
double r1 = ellp.MajorRadius();
|
||||
double r2 = ellp.MinorRadius();
|
||||
double f = c.FirstParameter();
|
||||
double l = c.LastParameter();
|
||||
gp_Pnt s = c.Value(f);
|
||||
gp_Pnt m = c.Value((l+f)/2.0);
|
||||
gp_Pnt e = c.Value(l);
|
||||
|
||||
// If the minor radius is very small compared to the major radius
|
||||
// the geometry actually degenerates to a line
|
||||
double ratio = std::min(r1,r2)/std::max(r1,r2);
|
||||
if (ratio < 0.001) {
|
||||
printGeneric(c, id, out);
|
||||
return;
|
||||
}
|
||||
|
||||
gp_Vec v1(m,s);
|
||||
gp_Vec v2(m,e);
|
||||
gp_Vec v3(0,0,1);
|
||||
double a = v3.DotCross(v1,v2);
|
||||
|
||||
// a full ellipse
|
||||
// See also https://developer.mozilla.org/en/SVG/Tutorial/Paths
|
||||
gp_Dir xaxis = ellp.XAxis().Direction();
|
||||
Standard_Real angle = xaxis.AngleWithRef(gp_Dir(1,0,0),gp_Dir(0,0,-1));
|
||||
angle = Base::toDegrees<double>(angle);
|
||||
if (fabs(l-f) > 1.0 && s.SquareDistance(e) < 0.001) {
|
||||
out << "<g transform = \"rotate(" << angle << "," << p.X() << "," << p.Y() << ")\">" << std::endl;
|
||||
out << "<ellipse cx =\"" << p.X() << "\" cy =\""
|
||||
<< p.Y() << "\" rx =\"" << r1 << "\" ry =\"" << r2 << "\"/>" << std::endl;
|
||||
out << "</g>" << std::endl;
|
||||
}
|
||||
// arc of ellipse
|
||||
else {
|
||||
char las = (l-f > D_PI) ? '1' : '0'; // large-arc-flag
|
||||
char swp = (a < 0) ? '1' : '0'; // sweep-flag, i.e. clockwise (0) or counter-clockwise (1)
|
||||
out << "<path d=\"M" << s.X() << " " << s.Y()
|
||||
<< " A" << r1 << " " << r2 << " "
|
||||
<< angle << " " << las << " " << swp << " "
|
||||
<< e.X() << " " << e.Y() << "\" />" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void SVGOutput::printBezier(const BRepAdaptor_Curve& c, int id, std::ostream& out)
|
||||
{
|
||||
try {
|
||||
std::stringstream str;
|
||||
str << "<path d=\"M";
|
||||
|
||||
Handle(Geom_BezierCurve) bezier = c.Bezier();
|
||||
Standard_Integer poles = bezier->NbPoles();
|
||||
|
||||
// if it's a bezier with degree higher than 3 convert it into a B-spline
|
||||
if (bezier->Degree() > 3 || bezier->IsRational()) {
|
||||
TopoDS_Edge edge = asBSpline(c, 3);
|
||||
if (!edge.IsNull()) {
|
||||
BRepAdaptor_Curve spline(edge);
|
||||
printBSpline(spline, id, out);
|
||||
}
|
||||
else {
|
||||
Standard_Failure::Raise("do it the generic way");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
gp_Pnt p1 = bezier->Pole(1);
|
||||
str << p1.X() << "," << p1.Y();
|
||||
if (bezier->Degree() == 3) {
|
||||
if (poles != 4)
|
||||
Standard_Failure::Raise("do it the generic way");
|
||||
gp_Pnt p2 = bezier->Pole(2);
|
||||
gp_Pnt p3 = bezier->Pole(3);
|
||||
gp_Pnt p4 = bezier->Pole(4);
|
||||
str << " C"
|
||||
<< p2.X() << "," << p2.Y() << " "
|
||||
<< p3.X() << "," << p3.Y() << " "
|
||||
<< p4.X() << "," << p4.Y() << " ";
|
||||
}
|
||||
else if (bezier->Degree() == 2) {
|
||||
if (poles != 3)
|
||||
Standard_Failure::Raise("do it the generic way");
|
||||
gp_Pnt p2 = bezier->Pole(2);
|
||||
gp_Pnt p3 = bezier->Pole(3);
|
||||
str << " Q"
|
||||
<< p2.X() << "," << p2.Y() << " "
|
||||
<< p3.X() << "," << p3.Y() << " ";
|
||||
}
|
||||
else if (bezier->Degree() == 1) {
|
||||
if (poles != 2)
|
||||
Standard_Failure::Raise("do it the generic way");
|
||||
gp_Pnt p2 = bezier->Pole(2);
|
||||
str << " L" << p2.X() << "," << p2.Y() << " ";
|
||||
}
|
||||
else {
|
||||
Standard_Failure::Raise("do it the generic way");
|
||||
}
|
||||
|
||||
str << "\" />";
|
||||
out << str.str();
|
||||
}
|
||||
catch (Standard_Failure&) {
|
||||
printGeneric(c, id, out);
|
||||
}
|
||||
}
|
||||
|
||||
void SVGOutput::printBSpline(const BRepAdaptor_Curve& c, int id, std::ostream& out)
|
||||
{
|
||||
try {
|
||||
std::stringstream str;
|
||||
Handle(Geom_BSplineCurve) spline;
|
||||
Standard_Real tol3D = 0.001;
|
||||
Standard_Integer maxDegree = 3, maxSegment = 100;
|
||||
Handle(BRepAdaptor_HCurve) hCurve = new BRepAdaptor_HCurve(c);
|
||||
// approximate the curve using a tolerance
|
||||
Approx_Curve3d approx(hCurve,tol3D,GeomAbs_C0,maxSegment,maxDegree);
|
||||
if (approx.IsDone() && approx.HasResult()) {
|
||||
// have the result
|
||||
spline = approx.Curve();
|
||||
} else {
|
||||
printGeneric(c, id, out);
|
||||
return;
|
||||
}
|
||||
|
||||
GeomConvert_BSplineCurveToBezierCurve crt(spline);
|
||||
Standard_Integer arcs = crt.NbArcs();
|
||||
str << "<path d=\"M";
|
||||
for (Standard_Integer i=1; i<=arcs; i++) {
|
||||
Handle(Geom_BezierCurve) bezier = crt.Arc(i);
|
||||
Standard_Integer poles = bezier->NbPoles();
|
||||
if (i == 1) {
|
||||
gp_Pnt p1 = bezier->Pole(1);
|
||||
str << p1.X() << "," << p1.Y();
|
||||
}
|
||||
if (bezier->Degree() == 3) {
|
||||
if (poles != 4)
|
||||
Standard_Failure::Raise("do it the generic way");
|
||||
gp_Pnt p2 = bezier->Pole(2);
|
||||
gp_Pnt p3 = bezier->Pole(3);
|
||||
gp_Pnt p4 = bezier->Pole(4);
|
||||
str << " C"
|
||||
<< p2.X() << "," << p2.Y() << " "
|
||||
<< p3.X() << "," << p3.Y() << " "
|
||||
<< p4.X() << "," << p4.Y() << " ";
|
||||
}
|
||||
else if (bezier->Degree() == 2) {
|
||||
if (poles != 3)
|
||||
Standard_Failure::Raise("do it the generic way");
|
||||
gp_Pnt p2 = bezier->Pole(2);
|
||||
gp_Pnt p3 = bezier->Pole(3);
|
||||
str << " Q"
|
||||
<< p2.X() << "," << p2.Y() << " "
|
||||
<< p3.X() << "," << p3.Y() << " ";
|
||||
}
|
||||
else if (bezier->Degree() == 1) {
|
||||
if (poles != 2)
|
||||
Standard_Failure::Raise("do it the generic way");
|
||||
gp_Pnt p2 = bezier->Pole(2);
|
||||
str << " L" << p2.X() << "," << p2.Y() << " ";
|
||||
}
|
||||
else {
|
||||
Standard_Failure::Raise("do it the generic way");
|
||||
}
|
||||
}
|
||||
|
||||
str << "\" />";
|
||||
out << str.str();
|
||||
}
|
||||
catch (Standard_Failure&) {
|
||||
printGeneric(c, id, out);
|
||||
}
|
||||
}
|
||||
|
||||
void SVGOutput::printGeneric(const BRepAdaptor_Curve& bac, int id, std::ostream& out)
|
||||
{
|
||||
TopLoc_Location location;
|
||||
Handle(Poly_Polygon3D) polygon = BRep_Tool::Polygon3D(bac.Edge(), location);
|
||||
if (!polygon.IsNull()) {
|
||||
const TColgp_Array1OfPnt& nodes = polygon->Nodes();
|
||||
char c = 'M';
|
||||
out << "<path id= \"" /*<< ViewName*/ << id << "\" d=\" ";
|
||||
for (int i = nodes.Lower(); i <= nodes.Upper(); i++){
|
||||
out << c << " " << nodes(i).X() << " " << nodes(i).Y()<< " " ;
|
||||
c = 'L';
|
||||
}
|
||||
out << "\" />" << endl;
|
||||
} else if (bac.GetType() == GeomAbs_Line) {
|
||||
//BRep_Tool::Polygon3D assumes the edge has polygon representation - ie already been "tessellated"
|
||||
//this is not true for all edges, especially "floating edges"
|
||||
double f = bac.FirstParameter();
|
||||
double l = bac.LastParameter();
|
||||
gp_Pnt s = bac.Value(f);
|
||||
gp_Pnt e = bac.Value(l);
|
||||
char c = 'M';
|
||||
out << "<path id= \"" /*<< ViewName*/ << id << "\" d=\" ";
|
||||
out << c << " " << s.X() << " " << s.Y()<< " " ;
|
||||
c = 'L';
|
||||
out << c << " " << e.X() << " " << e.Y()<< " " ;
|
||||
out << "\" />" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
DXFOutput::DXFOutput()
|
||||
{
|
||||
}
|
||||
|
||||
std::string DXFOutput::exportEdges(const TopoDS_Shape& input)
|
||||
{
|
||||
std::stringstream result;
|
||||
|
||||
TopExp_Explorer edges(input, TopAbs_EDGE);
|
||||
for (int i = 1 ; edges.More(); edges.Next(),i++) {
|
||||
const TopoDS_Edge& edge = TopoDS::Edge(edges.Current());
|
||||
BRepAdaptor_Curve adapt(edge);
|
||||
if (adapt.GetType() == GeomAbs_Circle) {
|
||||
printCircle(adapt, result);
|
||||
}
|
||||
else if (adapt.GetType() == GeomAbs_Ellipse) {
|
||||
printEllipse(adapt, i, result);
|
||||
}
|
||||
else if (adapt.GetType() == GeomAbs_BSplineCurve) {
|
||||
printBSpline(adapt, i, result);
|
||||
}
|
||||
// fallback
|
||||
else {
|
||||
printGeneric(adapt, i, result);
|
||||
}
|
||||
}
|
||||
|
||||
return result.str();
|
||||
}
|
||||
|
||||
void DXFOutput::printHeader( std::ostream& out)
|
||||
{
|
||||
out << 0 << endl;
|
||||
out << "SECTION" << endl;
|
||||
out << 2 << endl;
|
||||
out << "ENTITIES" << endl;
|
||||
}
|
||||
|
||||
void DXFOutput::printCircle(const BRepAdaptor_Curve& c, std::ostream& out)
|
||||
{
|
||||
gp_Circ circ = c.Circle();
|
||||
//const gp_Ax1& axis = c->Axis();
|
||||
const gp_Pnt& p= circ.Location();
|
||||
double r = circ.Radius();
|
||||
double f = c.FirstParameter();
|
||||
double l = c.LastParameter();
|
||||
gp_Pnt s = c.Value(f);
|
||||
gp_Pnt m = c.Value((l+f)/2.0);
|
||||
gp_Pnt e = c.Value(l);
|
||||
|
||||
gp_Vec v1(m,s);
|
||||
gp_Vec v2(m,e);
|
||||
gp_Vec v3(0,0,1);
|
||||
double a = v3.DotCross(v1,v2);
|
||||
|
||||
// a full circle
|
||||
if (s.SquareDistance(e) < 0.001) {
|
||||
//out << "<circle cx =\"" << p.X() << "\" cy =\""
|
||||
//<< p.Y() << "\" r =\"" << r << "\" />";
|
||||
out << 0 << endl;
|
||||
out << "CIRCLE" << endl;
|
||||
out << 8 << endl; // Group code for layer name
|
||||
out << "sheet_layer" << endl; // Layer number
|
||||
out << "100" << endl;
|
||||
out << "AcDbEntity" << endl;
|
||||
out << "100" << endl;
|
||||
out << "AcDbCircle" << endl;
|
||||
out << 10 << endl; // Centre X
|
||||
out << p.X() << endl; // X in WCS coordinates
|
||||
out << 20 << endl;
|
||||
out << p.Y() << endl; // Y in WCS coordinates
|
||||
out << 30 << endl;
|
||||
out << 0 << endl; // Z in WCS coordinates-leaving flat
|
||||
out << 40 << endl; //
|
||||
out << r << endl; // Radius
|
||||
}
|
||||
|
||||
|
||||
|
||||
// arc of circle
|
||||
else {
|
||||
// See also https://developer.mozilla.org/en/SVG/Tutorial/Paths
|
||||
/*char xar = '0'; // x-axis-rotation
|
||||
char las = (l-f > D_PI) ? '1' : '0'; // large-arc-flag
|
||||
char swp = (a < 0) ? '1' : '0'; // sweep-flag, i.e. clockwise (0) or counter-clockwise (1)
|
||||
out << "<path d=\"M" << s.X() << " " << s.Y()
|
||||
<< " A" << r << " " << r << " "
|
||||
<< xar << " " << las << " " << swp << " "
|
||||
<< e.X() << " " << e.Y() << "\" />";*/
|
||||
double ax = s.X() - p.X();
|
||||
double ay = s.Y() - p.Y();
|
||||
double bx = e.X() - p.X();
|
||||
double by = e.Y() - p.Y();
|
||||
|
||||
double start_angle = atan2(ay, ax) * 180/D_PI;
|
||||
double end_angle = atan2(by, bx) * 180/D_PI;
|
||||
|
||||
|
||||
if(a > 0){
|
||||
double temp = start_angle;
|
||||
start_angle = end_angle;
|
||||
end_angle = temp;}
|
||||
out << 0 << endl;
|
||||
out << "ARC" << endl;
|
||||
out << 8 << endl; // Group code for layer name
|
||||
out << "sheet_layer" << endl; // Layer number
|
||||
out << "100" << endl;
|
||||
out << "AcDbEntity" << endl;
|
||||
out << "100" << endl;
|
||||
out << "AcDbCircle" << endl;
|
||||
out << 10 << endl; // Centre X
|
||||
out << p.X() << endl; // X in WCS coordinates
|
||||
out << 20 << endl;
|
||||
out << p.Y() << endl; // Y in WCS coordinates
|
||||
out << 30 << endl;
|
||||
out << 0 << endl; // Z in WCS coordinates
|
||||
out << 40 << endl; //
|
||||
out << r << endl; // Radius
|
||||
out << "100" << endl;
|
||||
out << "AcDbArc" << endl;
|
||||
out << 50 << endl;
|
||||
out << start_angle << endl; // Start angle
|
||||
out << 51 << endl;
|
||||
out << end_angle << endl; // End angle
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void DXFOutput::printEllipse(const BRepAdaptor_Curve& c, int /*id*/, std::ostream& out)
|
||||
{
|
||||
gp_Elips ellp = c.Ellipse();
|
||||
const gp_Pnt& p= ellp.Location();
|
||||
double r1 = ellp.MajorRadius();
|
||||
double r2 = ellp.MinorRadius();
|
||||
double dp = ellp.Axis().Direction().Dot(gp_Vec(0,0,1));
|
||||
|
||||
// a full ellipse
|
||||
/* if (s.SquareDistance(e) < 0.001) {
|
||||
out << "<ellipse cx =\"" << p.X() << "\" cy =\""
|
||||
<< p.Y() << "\" rx =\"" << r1 << "\" ry =\"" << r2 << "\"/>";
|
||||
}
|
||||
// arc of ellipse
|
||||
else {
|
||||
// See also https://developer.mozilla.org/en/SVG/Tutorial/Paths
|
||||
gp_Dir xaxis = ellp.XAxis().Direction();
|
||||
Standard_Real angle = xaxis.Angle(gp_Dir(1,0,0));
|
||||
angle = Base::toDegrees<double>(angle);
|
||||
char las = (l-f > D_PI) ? '1' : '0'; // large-arc-flag
|
||||
char swp = (a < 0) ? '1' : '0'; // sweep-flag, i.e. clockwise (0) or counter-clockwise (1)
|
||||
out << "<path d=\"M" << s.X() << " " << s.Y()
|
||||
<< " A" << r1 << " " << r2 << " "
|
||||
<< angle << " " << las << " " << swp << " "
|
||||
<< e.X() << " " << e.Y() << "\" />";
|
||||
}*/
|
||||
gp_Dir xaxis = ellp.XAxis().Direction();
|
||||
double angle = xaxis.AngleWithRef(gp_Dir(1,0,0),gp_Dir(0,0,-1));
|
||||
//double rotation = Base::toDegrees<double>(angle);
|
||||
|
||||
double start_angle = c.FirstParameter();
|
||||
double end_angle = c.LastParameter();
|
||||
|
||||
double major_x;double major_y;
|
||||
|
||||
major_x = r1 * cos(angle);
|
||||
major_y = r1 * sin(angle);
|
||||
|
||||
double ratio = r2/r1;
|
||||
|
||||
if(dp < 0){
|
||||
double temp = start_angle;
|
||||
start_angle = end_angle;
|
||||
end_angle = temp;
|
||||
}
|
||||
out << 0 << endl;
|
||||
out << "ELLIPSE" << endl;
|
||||
out << 8 << endl; // Group code for layer name
|
||||
out << "sheet_layer" << endl; // Layer number
|
||||
out << "100" << endl;
|
||||
out << "AcDbEntity" << endl;
|
||||
out << "100" << endl;
|
||||
out << "AcDbEllipse" << endl;
|
||||
out << 10 << endl; // Centre X
|
||||
out << p.X() << endl; // X in WCS coordinates
|
||||
out << 20 << endl;
|
||||
out << p.Y() << endl; // Y in WCS coordinates
|
||||
out << 30 << endl;
|
||||
out << 0 << endl; // Z in WCS coordinates
|
||||
out << 11 << endl; //
|
||||
out << major_x << endl; // Major X
|
||||
out << 21 << endl;
|
||||
out << major_y << endl; // Major Y
|
||||
out << 31 << endl;
|
||||
out << 0 << endl; // Major Z
|
||||
out << 40 << endl; //
|
||||
out << ratio << endl; // Ratio
|
||||
out << 41 << endl;
|
||||
out << start_angle << endl; // Start angle
|
||||
out << 42 << endl;
|
||||
out << end_angle << endl; // End angle
|
||||
}
|
||||
|
||||
void DXFOutput::printBSpline(const BRepAdaptor_Curve& c, int id, std::ostream& out) //Not even close yet- DF
|
||||
{
|
||||
try {
|
||||
std::stringstream str;
|
||||
Handle(Geom_BSplineCurve) spline;
|
||||
Standard_Real tol3D = 0.001;
|
||||
Standard_Integer maxDegree = 3, maxSegment = 50;
|
||||
Handle(BRepAdaptor_HCurve) hCurve = new BRepAdaptor_HCurve(c);
|
||||
// approximate the curve using a tolerance
|
||||
Approx_Curve3d approx(hCurve,tol3D,GeomAbs_C0,maxSegment,maxDegree);
|
||||
if (approx.IsDone() && approx.HasResult()) {
|
||||
// have the result
|
||||
spline = approx.Curve();
|
||||
} else {
|
||||
printGeneric(c, id, out);
|
||||
return;
|
||||
}
|
||||
|
||||
//GeomConvert_BSplineCurveToBezierCurve crt(spline);
|
||||
//GeomConvert_BSplineCurveKnotSplitting crt(spline,0);
|
||||
//Standard_Integer arcs = crt.NbArcs();
|
||||
//Standard_Integer arcs = crt.NbSplits()-1;
|
||||
Standard_Integer m = 0;
|
||||
if (spline->IsPeriodic()) {
|
||||
m = spline->NbPoles() + 2*spline->Degree() - spline->Multiplicity(1) + 2;
|
||||
}
|
||||
else {
|
||||
for (int i=1; i<= spline->NbKnots(); i++)
|
||||
m += spline->Multiplicity(i);
|
||||
}
|
||||
TColStd_Array1OfReal knotsequence(1,m);
|
||||
spline->KnotSequence(knotsequence);
|
||||
TColgp_Array1OfPnt poles(1,spline->NbPoles());
|
||||
spline->Poles(poles);
|
||||
|
||||
|
||||
str << 0 << endl
|
||||
<< "SPLINE" << endl
|
||||
<< 8 << endl // Group code for layer name
|
||||
<< "sheet_layer" << endl // Layer name
|
||||
<< "100" << endl
|
||||
<< "AcDbEntity" << endl
|
||||
<< "100" << endl
|
||||
<< "AcDbSpline" << endl
|
||||
<< 70 << endl
|
||||
<< spline->IsRational()*4 << endl //flags
|
||||
<< 71 << endl << spline->Degree() << endl
|
||||
<< 72 << endl << knotsequence.Length() << endl
|
||||
<< 73 << endl << poles.Length() << endl
|
||||
<< 74 << endl << 0 << endl; //fitpoints
|
||||
|
||||
for (int i = knotsequence.Lower() ; i <= knotsequence.Upper(); i++) {
|
||||
str << 40 << endl << knotsequence(i) << endl;
|
||||
}
|
||||
for (int i = poles.Lower(); i <= poles.Upper(); i++) {
|
||||
gp_Pnt pole = poles(i);
|
||||
str << 10 << endl << pole.X() << endl
|
||||
<< 20 << endl << pole.Y() << endl
|
||||
<< 30 << endl << pole.Z() << endl;
|
||||
if (spline->IsRational()) {
|
||||
str << 41 << endl << spline->Weight(i) << endl;
|
||||
}
|
||||
}
|
||||
|
||||
//str << "\" />";
|
||||
out << str.str();
|
||||
}
|
||||
catch (Standard_Failure&) {
|
||||
printGeneric(c, id, out);
|
||||
}
|
||||
}
|
||||
|
||||
void DXFOutput::printGeneric(const BRepAdaptor_Curve& c, int /*id*/, std::ostream& out)
|
||||
{
|
||||
double uStart = c.FirstParameter();
|
||||
gp_Pnt PS;
|
||||
gp_Vec VS;
|
||||
c.D1(uStart, PS, VS);
|
||||
|
||||
double uEnd = c.LastParameter();
|
||||
gp_Pnt PE;
|
||||
gp_Vec VE;
|
||||
c.D1(uEnd, PE, VE);
|
||||
|
||||
out << "0" << endl;
|
||||
out << "LINE" << endl;
|
||||
out << "8" << endl; // Group code for layer name
|
||||
out << "sheet_layer" << endl; // Layer name
|
||||
out << "100" << endl;
|
||||
out << "AcDbEntity" << endl;
|
||||
out << "100" << endl;
|
||||
out << "AcDbLine" << endl;
|
||||
out << "10" << endl; // Start point of line
|
||||
out << PS.X() << endl; // X in WCS coordinates
|
||||
out << "20" << endl;
|
||||
out << PS.Y() << endl; // Y in WCS coordinates
|
||||
out << "30" << endl;
|
||||
out << "0" << endl; // Z in WCS coordinates
|
||||
out << "11" << endl; // End point of line
|
||||
out << PE.X() << endl; // X in WCS coordinates
|
||||
out << "21" << endl;
|
||||
out << PE.Y() << endl; // Y in WCS coordinates
|
||||
out << "31" << endl;
|
||||
out << "0" << endl; // Z in WCS coordinates
|
||||
}
|
||||
80
src/Mod/TechDraw/App/TechDrawExport.h
Normal file
80
src/Mod/TechDraw/App/TechDrawExport.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2011 Werner Mayer <wmayer[at]users.sourceforge.net> *
|
||||
* *
|
||||
* 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 *
|
||||
* *
|
||||
***************************************************************************/
|
||||
//this file originally part of TechDraw workbench
|
||||
//migrated to TechDraw workbench 2022-01-26 by Wandererfan
|
||||
|
||||
|
||||
#ifndef TECHDRAW_EXPORT_H
|
||||
#define TECHDRAW_EXPORT_H
|
||||
|
||||
#include <Mod/TechDraw/TechDrawGlobal.h>
|
||||
|
||||
#include <string>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
|
||||
class TopoDS_Shape;
|
||||
class BRepAdaptor_Curve;
|
||||
|
||||
namespace TechDraw
|
||||
{
|
||||
|
||||
class TechDrawExport TechDrawOutput
|
||||
{
|
||||
public:
|
||||
// If the curve is approximately a circle it will be returned,
|
||||
// otherwise a null edge is returned.
|
||||
TopoDS_Edge asCircle(const BRepAdaptor_Curve&) const;
|
||||
TopoDS_Edge asBSpline(const BRepAdaptor_Curve&, int maxDegree) const;
|
||||
};
|
||||
|
||||
class TechDrawExport SVGOutput : public TechDrawOutput
|
||||
{
|
||||
public:
|
||||
SVGOutput();
|
||||
std::string exportEdges(const TopoDS_Shape&);
|
||||
|
||||
private:
|
||||
void printCircle(const BRepAdaptor_Curve&, std::ostream&);
|
||||
void printEllipse(const BRepAdaptor_Curve&, int id, std::ostream&);
|
||||
void printBSpline(const BRepAdaptor_Curve&, int id, std::ostream&);
|
||||
void printBezier(const BRepAdaptor_Curve&, int id, std::ostream&);
|
||||
void printGeneric(const BRepAdaptor_Curve&, int id, std::ostream&);
|
||||
};
|
||||
|
||||
/* dxf output section - Dan Falck 2011/09/25 */
|
||||
class TechDrawExport DXFOutput : public TechDrawOutput
|
||||
{
|
||||
public:
|
||||
DXFOutput();
|
||||
std::string exportEdges(const TopoDS_Shape&);
|
||||
|
||||
private:
|
||||
void printHeader(std::ostream& out);
|
||||
void printCircle(const BRepAdaptor_Curve&, std::ostream&);
|
||||
void printEllipse(const BRepAdaptor_Curve&, int id, std::ostream&);
|
||||
void printBSpline(const BRepAdaptor_Curve&, int id, std::ostream&);
|
||||
void printGeneric(const BRepAdaptor_Curve&, int id, std::ostream&);
|
||||
};
|
||||
|
||||
} //namespace TechDraw
|
||||
|
||||
#endif // TECHDRAW_EXPORT_H
|
||||
Reference in New Issue
Block a user