FreeCAD/src/Mod/Drawing/App/ProjectionAlgos.cpp

369 lines
14 KiB
C++

/***************************************************************************
* 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 *
* *
***************************************************************************/
#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 <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 <BRep_Tool.hxx>
#include <BRepMesh.hxx>
#include <BRepAdaptor_CompCurve.hxx>
#include <Handle_BRepAdaptor_HCompCurve.hxx>
#include <Approx_Curve3d.hxx>
#include <BRepAdaptor_HCurve.hxx>
#include <Handle_BRepAdaptor_HCurve.hxx>
#include <Geom_BSplineCurve.hxx>
#include <Handle_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 "DrawingExport.h"
using namespace Drawing;
using namespace std;
//===========================================================================
// ProjectionAlgos
//===========================================================================
ProjectionAlgos::ProjectionAlgos(const TopoDS_Shape &Input, const Base::Vector3f &Dir)
: Input(Input), Direction(Dir)
{
execute();
}
ProjectionAlgos::~ProjectionAlgos()
{
}
TopoDS_Shape ProjectionAlgos::invertY(const TopoDS_Shape& shape)
{
// make sure to have the y coordinates inverted
gp_Trsf mat;
Bnd_Box bounds;
BRepBndLib::Add(shape, bounds);
bounds.SetGap(0.0);
Standard_Real xMin, yMin, zMin, xMax, yMax, zMax;
bounds.Get(xMin, yMin, zMin, xMax, yMax, zMax);
mat.SetMirror(gp_Ax2(gp_Pnt((xMin+xMax)/2,(yMin+yMax)/2,(zMin+zMax)/2), gp_Dir(0,1,0)));
BRepBuilderAPI_Transform mkTrf(shape, mat);
return mkTrf.Shape();
}
void ProjectionAlgos::execute(void)
{
Handle( HLRBRep_Algo ) brep_hlr = new HLRBRep_Algo;
brep_hlr->Add(Input);
try {
#if defined(__GNUC__) && defined (FC_OS_LINUX)
Base::SignalException se;
#endif
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();
}
catch (...) {
Standard_Failure::Raise("Fatal error occurred while projecting shape");
}
// extracting the result sets:
HLRBRep_HLRToShape shapes( brep_hlr );
V = shapes.VCompound ();// hard edge visibly
V1 = shapes.Rg1LineVCompound();// Smoth edges visibly
VN = shapes.RgNLineVCompound();// contour edges visibly
VO = shapes.OutLineVCompound();// contours apparents visibly
VI = shapes.IsoLineVCompound();// isoparamtriques visibly
H = shapes.HCompound ();// hard edge invisibly
H1 = shapes.Rg1LineHCompound();// Smoth edges invisibly
HN = shapes.RgNLineHCompound();// contour edges invisibly
HO = shapes.OutLineHCompound();// contours apparents invisibly
HI = shapes.IsoLineHCompound();// isoparamtriques invisibly
}
std::string ProjectionAlgos::getSVG(SvgExtractionType type, float scale)
{
std::stringstream result;
SVGOutput output;
if (!H.IsNull() && (type & WithHidden)) {
float width = 0.15f/scale;
BRepMesh::Mesh(H,0.1);
result << "<g"
//<< " id=\"" << ViewName << "\"" << endl
<< " stroke=\"rgb(0, 0, 0)\"" << endl
<< " stroke-width=\"" << width << "\"" << endl
<< " stroke-linecap=\"butt\"" << endl
<< " stroke-linejoin=\"miter\"" << endl
<< " stroke-dasharray=\"5 3\"" << endl
<< " fill=\"none\"" << endl
<< " >" << endl
<< output.exportEdges(H)
<< "</g>" << endl;
}
if (!HO.IsNull() && (type & WithHidden)) {
float width = 0.15f/scale;
BRepMesh::Mesh(HO,0.1);
result << "<g"
//<< " id=\"" << ViewName << "\"" << endl
<< " stroke=\"rgb(0, 0, 0)\"" << endl
<< " stroke-width=\"" << width << "\"" << endl
<< " stroke-linecap=\"butt\"" << endl
<< " stroke-linejoin=\"miter\"" << endl
<< " stroke-dasharray=\"5 3\"" << endl
<< " fill=\"none\"" << endl
<< " >" << endl
<< output.exportEdges(HO)
<< "</g>" << endl;
}
if (!VO.IsNull()) {
float width = 0.35f/scale;
BRepMesh::Mesh(VO,0.1);
result << "<g"
//<< " id=\"" << ViewName << "\"" << endl
<< " stroke=\"rgb(0, 0, 0)\"" << endl
<< " stroke-width=\"" << width << "\"" << endl
<< " stroke-linecap=\"butt\"" << endl
<< " stroke-linejoin=\"miter\"" << endl
<< " fill=\"none\"" << endl
<< " >" << endl
<< output.exportEdges(VO)
<< "</g>" << endl;
}
if (!V.IsNull()) {
float width = 0.35f/scale;
BRepMesh::Mesh(V,0.1);
result << "<g"
//<< " id=\"" << ViewName << "\"" << endl
<< " stroke=\"rgb(0, 0, 0)\"" << endl
<< " stroke-width=\"" << width << "\"" << endl
<< " stroke-linecap=\"butt\"" << endl
<< " stroke-linejoin=\"miter\"" << endl
<< " fill=\"none\"" << endl
<< " >" << endl
<< output.exportEdges(V)
<< "</g>" << endl;
}
if (!V1.IsNull() && (type & WithSmooth)) {
float width = 0.35f/scale;
BRepMesh::Mesh(V1,0.1);
result << "<g"
//<< " id=\"" << ViewName << "\"" << endl
<< " stroke=\"rgb(0, 0, 0)\"" << endl
<< " stroke-width=\"" << width << "\"" << endl
<< " stroke-linecap=\"butt\"" << endl
<< " stroke-linejoin=\"miter\"" << endl
<< " fill=\"none\"" << endl
<< " >" << endl
<< output.exportEdges(V1)
<< "</g>" << endl;
}
if (!H1.IsNull() && (type & WithSmooth) && (type & WithHidden)) {
float width = 0.15f/scale;
BRepMesh::Mesh(H1,0.1);
result << "<g"
//<< " id=\"" << ViewName << "\"" << endl
<< " stroke=\"rgb(0, 0, 0)\"" << endl
<< " stroke-width=\"" << width << "\"" << endl
<< " stroke-linecap=\"butt\"" << endl
<< " stroke-linejoin=\"miter\"" << endl
<< " stroke-dasharray=\"5 3\"" << endl
<< " fill=\"none\"" << endl
<< " >" << endl
<< output.exportEdges(H1)
<< "</g>" << endl;
}
/*result << "0" << endl
<< "SECTION" << endl
<< "2" << endl
<< "ENTITIES" << endl;*/
return result.str();
}
/* dxf output section - Dan Falck 2011/09/25 */
std::string ProjectionAlgos::getDXF(SvgExtractionType type, float scale)
{
std::stringstream result;
DXFOutput output;
result << "0" << endl
<< "SECTION" << endl
<< "2" << endl
<< "ENTITIES" << endl;
if (!H.IsNull() && (type & WithHidden)) {
float width = 0.15f/scale;
BRepMesh::Mesh(H,0.1);
result //<< "<g"
//<< " id=\"" << ViewName << "\"" << endl
/*<< " stroke=\"rgb(0, 0, 0)\"" << endl
<< " stroke-width=\"" << width << "\"" << endl
<< " stroke-linecap=\"butt\"" << endl
<< " stroke-linejoin=\"miter\"" << endl
<< " stroke-dasharray=\"5 3\"" << endl
<< " fill=\"none\"" << endl
<< " >" << endl*/
<< output.exportEdges(H);
//<< "</g>" << endl;
}
if (!HO.IsNull() && (type & WithHidden)) {
float width = 0.15f/scale;
BRepMesh::Mesh(HO,0.1);
result //<< "<g"
//<< " id=\"" << ViewName << "\"" << endl
/*<< " stroke=\"rgb(0, 0, 0)\"" << endl
<< " stroke-width=\"" << width << "\"" << endl
<< " stroke-linecap=\"butt\"" << endl
<< " stroke-linejoin=\"miter\"" << endl
<< " stroke-dasharray=\"5 3\"" << endl
<< " fill=\"none\"" << endl
<< " >" << endl*/
<< output.exportEdges(HO);
//<< "</g>" << endl;
}
if (!VO.IsNull()) {
float width = 0.35f/scale;
BRepMesh::Mesh(VO,0.1);
result //<< "<g"
//<< " id=\"" << ViewName << "\"" << endl
/*<< " stroke=\"rgb(0, 0, 0)\"" << endl
<< " stroke-width=\"" << width << "\"" << endl
<< " stroke-linecap=\"butt\"" << endl
<< " stroke-linejoin=\"miter\"" << endl
<< " fill=\"none\"" << endl
<< " >" << endl*/
<< output.exportEdges(VO);
//<< "</g>" << endl;
}
if (!V.IsNull()) {
float width = 0.35f/scale;
BRepMesh::Mesh(V,0.1);
result //<< "<g"
//<< " id=\"" << ViewName << "\"" << endl
/*<< " stroke=\"rgb(0, 0, 0)\"" << endl
<< " stroke-width=\"" << width << "\"" << endl
<< " stroke-linecap=\"butt\"" << endl
<< " stroke-linejoin=\"miter\"" << endl
<< " fill=\"none\"" << endl
<< " >" << endl*/
<< output.exportEdges(V);
//<< "</g>" << endl;
}
if (!V1.IsNull() && (type & WithSmooth)) {
float width = 0.35f/scale;
BRepMesh::Mesh(V1,0.1);
result //<< "<g"
//<< " id=\"" << ViewName << "\"" << endl
/* << " stroke=\"rgb(0, 0, 0)\"" << endl
<< " stroke-width=\"" << width << "\"" << endl
<< " stroke-linecap=\"butt\"" << endl
<< " stroke-linejoin=\"miter\"" << endl
<< " fill=\"none\"" << endl
<< " >" << endl*/
<< output.exportEdges(V1);
//<< "</g>" << endl;
}
if (!H1.IsNull() && (type & WithSmooth) && (type & WithHidden)) {
float width = 0.15f/scale;
BRepMesh::Mesh(H1,0.1);
result //<< "<g"
//<< " id=\"" << ViewName << "\"" << endl
/*<< " stroke=\"rgb(0, 0, 0)\"" << endl
<< " stroke-width=\"" << width << "\"" << endl
<< " stroke-linecap=\"butt\"" << endl
<< " stroke-linejoin=\"miter\"" << endl
<< " stroke-dasharray=\"5 3\"" << endl
<< " fill=\"none\"" << endl
<< " >" << endl*/
<< output.exportEdges(H1);
//<< "</g>" << endl;
}
result << 0 << endl
<< "ENDSEC" << endl
<< 0 << endl
<< "EOF";
return result.str();
}