add new feature "Projection on surface"
This commit is contained in:
committed by
wmayer
parent
d3351496d9
commit
1c5ee376e6
@@ -2386,7 +2386,7 @@ CmdPartProjectionOnSurface::CmdPartProjectionOnSurface()
|
||||
sToolTipText = QT_TR_NOOP("Create projection on surface...");
|
||||
sWhatsThis = "Part_projectionOnSurface";
|
||||
sStatusTip = sToolTipText;
|
||||
sPixmap = "Part_Extrude";
|
||||
sPixmap = "Part_ProjectionOnSurface";
|
||||
}
|
||||
|
||||
void CmdPartProjectionOnSurface::activated(int iMsg)
|
||||
|
||||
@@ -1,31 +1,965 @@
|
||||
#include "PreCompiled.h"
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2019 Manuel Apeltauer, direkt cnc-systeme GmbH *
|
||||
* *
|
||||
* 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"
|
||||
#include "DlgProjectionOnSurface.h"
|
||||
#include "ui_DlgProjectionOnSurface.h"
|
||||
|
||||
#include <Gui/BitmapFactory.h>
|
||||
|
||||
#include "Gui/MainWindow.h"
|
||||
#include "Gui/MDIView.h"
|
||||
#include "Gui/View3DInventor.h"
|
||||
#include "Gui/View3DInventorViewer.h"
|
||||
#include "Inventor/SbVec3d.h"
|
||||
#include "Gui/Application.h"
|
||||
|
||||
#include "ViewProviderExt.h"
|
||||
|
||||
#include <TopExp.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
#include <BRepProj_Projection.hxx>
|
||||
#include <TopoDS_Builder.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <ShapeAnalysis.hxx>
|
||||
#include <ShapeAnalysis_FreeBounds.hxx>
|
||||
#include <ShapeFix_Wire.hxx>
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <BRepBuilderAPI_MakeWire.hxx>
|
||||
#include <Geom_TrimmedCurve.hxx>
|
||||
#include <GeomProjLib.hxx>
|
||||
#include <BRepBuilderAPI_MakeEdge.hxx>
|
||||
#include "ShapeFix_Edge.hxx"
|
||||
#include <BRepBuilderAPI_MakeFace.hxx>
|
||||
#include <ShapeFix_Face.hxx>
|
||||
#include <BRepCheck_Analyzer.hxx>
|
||||
#include <ShapeFix_Wireframe.hxx>
|
||||
#include <BRepPrimAPI_MakePrism.hxx>
|
||||
|
||||
using namespace PartGui;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
class DlgProjectionOnSurface::EdgeSelection : public Gui::SelectionFilterGate
|
||||
{
|
||||
public:
|
||||
bool canSelect;
|
||||
|
||||
EdgeSelection()
|
||||
: Gui::SelectionFilterGate((Gui::SelectionFilter*)0)
|
||||
{
|
||||
canSelect = false;
|
||||
}
|
||||
~EdgeSelection() {}
|
||||
|
||||
bool allow(App::Document* /*pDoc*/, App::DocumentObject* iPObj, const char* sSubName)
|
||||
{
|
||||
Part::Feature* aPart = dynamic_cast<Part::Feature*>(iPObj);
|
||||
if (!aPart) return false;
|
||||
if (!sSubName) return false;
|
||||
std::string subName(sSubName);
|
||||
if (subName.empty()) return false;
|
||||
|
||||
auto subShape = aPart->Shape.getShape().getSubShape(sSubName);
|
||||
if (subShape.IsNull()) return false;
|
||||
auto type = subShape.ShapeType();
|
||||
if (type != TopAbs_EDGE) return false;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
class DlgProjectionOnSurface::FaceSelection : public Gui::SelectionFilterGate
|
||||
{
|
||||
public:
|
||||
bool canSelect;
|
||||
|
||||
FaceSelection()
|
||||
: Gui::SelectionFilterGate((Gui::SelectionFilter*)0)
|
||||
{
|
||||
canSelect = false;
|
||||
}
|
||||
~FaceSelection() {}
|
||||
|
||||
bool allow(App::Document* /*pDoc*/, App::DocumentObject* iPObj, const char* sSubName)
|
||||
{
|
||||
Part::Feature* aPart = dynamic_cast<Part::Feature*>(iPObj);
|
||||
if (!aPart) return false;
|
||||
if (!sSubName) return false;
|
||||
std::string subName(sSubName);
|
||||
if (subName.empty()) return false;
|
||||
|
||||
auto subShape = aPart->Shape.getShape().getSubShape(sSubName);
|
||||
if (subShape.IsNull()) return false;
|
||||
auto type = subShape.ShapeType();
|
||||
if (type != TopAbs_FACE) return false;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
using namespace PartGui;
|
||||
|
||||
DlgProjectionOnSurface::DlgProjectionOnSurface(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::DlgProjectionOnSurface)
|
||||
DlgProjectionOnSurface::DlgProjectionOnSurface(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, ui(new Ui::DlgProjectionOnSurface)
|
||||
, m_projectionObjectName(tr("Projection Object"))
|
||||
, filterEdge(nullptr)
|
||||
, filterFace(nullptr)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->pushButtonAddEdge->setCheckable(true);
|
||||
ui->pushButtonAddFace->setCheckable(true);
|
||||
ui->pushButtonAddProjFace->setCheckable(true);
|
||||
ui->pushButtonAddWire->setCheckable(true);
|
||||
|
||||
m_guiObjectVec.push_back(ui->pushButtonAddEdge);
|
||||
m_guiObjectVec.push_back(ui->pushButtonAddFace);
|
||||
m_guiObjectVec.push_back(ui->pushButtonAddProjFace);
|
||||
m_guiObjectVec.push_back(ui->pushButtonDirX);
|
||||
m_guiObjectVec.push_back(ui->pushButtonDirY);
|
||||
m_guiObjectVec.push_back(ui->pushButtonDirZ);
|
||||
m_guiObjectVec.push_back(ui->pushButtonGetCurrentCamDir);
|
||||
m_guiObjectVec.push_back(ui->radioButtonShowAll);
|
||||
m_guiObjectVec.push_back(ui->radioButtonFaces);
|
||||
m_guiObjectVec.push_back(ui->radioButtonEdges);
|
||||
m_guiObjectVec.push_back(ui->pushButtonAddWire);
|
||||
|
||||
get_camera_direction();
|
||||
disable_ui_elements(m_guiObjectVec, ui->pushButtonAddProjFace);
|
||||
|
||||
App::Document* activeDoc = App::GetApplication().getActiveDocument();
|
||||
if (!activeDoc)
|
||||
{
|
||||
throw Base::ValueError(QString(tr("Have no active document!!!")).toUtf8());
|
||||
return;
|
||||
}
|
||||
m_projectionObject = dynamic_cast<Part::Feature*>(activeDoc->addObject("Part::Feature", std::string(m_projectionObjectName.toUtf8()).c_str()));
|
||||
if ( !m_projectionObject )
|
||||
{
|
||||
throw Base::ValueError(QString(tr("Can not create a projection object!!!")).toUtf8());
|
||||
return;
|
||||
}
|
||||
on_radioButtonShowAll_clicked();
|
||||
m_lastDepthVal = ui->doubleSpinBoxSolidDepth->value();
|
||||
}
|
||||
|
||||
DlgProjectionOnSurface::~DlgProjectionOnSurface()
|
||||
{
|
||||
delete ui;
|
||||
delete ui;
|
||||
for ( auto it : m_projectionSurfaceVec)
|
||||
{
|
||||
higlight_object(it.partFeature, it.partName, false, 0);
|
||||
PartGui::ViewProviderPartExt* vp = dynamic_cast<PartGui::ViewProviderPartExt*>(Gui::Application::Instance->getViewProvider(it.partFeature));
|
||||
if (vp)
|
||||
{
|
||||
vp->Selectable.setValue(it.is_selectable);
|
||||
vp->Transparency.setValue(it.transparency);
|
||||
}
|
||||
}
|
||||
for (auto it : m_shapeVec)
|
||||
{
|
||||
higlight_object(it.partFeature, it.partName, false, 0);
|
||||
}
|
||||
Gui::Selection().rmvSelectionGate();
|
||||
}
|
||||
|
||||
void PartGui::DlgProjectionOnSurface::apply(void)
|
||||
{
|
||||
}
|
||||
|
||||
void PartGui::DlgProjectionOnSurface::reject(void)
|
||||
{
|
||||
App::Document* activeDoc = App::GetApplication().getActiveDocument();
|
||||
if (!activeDoc) return;
|
||||
activeDoc->removeObject(m_projectionObject->getNameInDocument());
|
||||
}
|
||||
|
||||
void PartGui::DlgProjectionOnSurface::on_pushButtonAddFace_clicked()
|
||||
{
|
||||
if ( ui->pushButtonAddFace->isChecked() )
|
||||
{
|
||||
m_currentSelection = "add_face";
|
||||
disable_ui_elements(m_guiObjectVec, ui->pushButtonAddFace);
|
||||
if (!filterFace)
|
||||
{
|
||||
filterFace = new FaceSelection();
|
||||
Gui::Selection().addSelectionGate(filterFace);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_currentSelection = "";
|
||||
enable_ui_elements(m_guiObjectVec, nullptr);
|
||||
Gui::Selection().rmvSelectionGate();
|
||||
filterFace = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void PartGui::DlgProjectionOnSurface::on_pushButtonAddEdge_clicked()
|
||||
{
|
||||
if (ui->pushButtonAddEdge->isChecked())
|
||||
{
|
||||
m_currentSelection = "add_edge";
|
||||
disable_ui_elements(m_guiObjectVec, ui->pushButtonAddEdge);
|
||||
if (!filterEdge)
|
||||
{
|
||||
filterEdge = new EdgeSelection();
|
||||
Gui::Selection().addSelectionGate(filterEdge);
|
||||
}
|
||||
ui->radioButtonEdges->setChecked(true);
|
||||
on_radioButtonEdges_clicked();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_currentSelection = "";
|
||||
enable_ui_elements(m_guiObjectVec, nullptr);
|
||||
Gui::Selection().rmvSelectionGate();
|
||||
filterEdge = nullptr;
|
||||
}
|
||||
}
|
||||
void PartGui::DlgProjectionOnSurface::on_pushButtonGetCurrentCamDir_clicked()
|
||||
{
|
||||
get_camera_direction();
|
||||
}
|
||||
|
||||
void PartGui::DlgProjectionOnSurface::on_pushButtonDirX_clicked()
|
||||
{
|
||||
set_xyz_dir_spinbox(ui->doubleSpinBoxDirX);
|
||||
}
|
||||
|
||||
void PartGui::DlgProjectionOnSurface::on_pushButtonDirY_clicked()
|
||||
{
|
||||
set_xyz_dir_spinbox(ui->doubleSpinBoxDirY);
|
||||
}
|
||||
|
||||
void PartGui::DlgProjectionOnSurface::on_pushButtonDirZ_clicked()
|
||||
{
|
||||
set_xyz_dir_spinbox(ui->doubleSpinBoxDirZ);
|
||||
}
|
||||
|
||||
void PartGui::DlgProjectionOnSurface::onSelectionChanged(const Gui::SelectionChanges& msg)
|
||||
{
|
||||
if (msg.Type == Gui::SelectionChanges::AddSelection)
|
||||
{
|
||||
if ( m_currentSelection == "add_face" || m_currentSelection == "add_edge" || m_currentSelection == "add_wire")
|
||||
{
|
||||
store_current_selected_parts(m_shapeVec, 0xff00ff00);
|
||||
create_projection_wire(m_shapeVec);
|
||||
create_projection_face_from_wire(m_shapeVec);
|
||||
create_face_extrude(m_shapeVec);
|
||||
show_projected_shapes(m_shapeVec);
|
||||
}
|
||||
else if (m_currentSelection == "add_projection_surface")
|
||||
{
|
||||
m_projectionSurfaceVec.clear();
|
||||
store_current_selected_parts(m_projectionSurfaceVec, 0xffff0000);
|
||||
if (m_projectionSurfaceVec.size())
|
||||
{
|
||||
PartGui::ViewProviderPartExt* vp = dynamic_cast<PartGui::ViewProviderPartExt*>(Gui::Application::Instance->getViewProvider(m_projectionSurfaceVec.back().partFeature));
|
||||
if (vp)
|
||||
{
|
||||
vp->Selectable.setValue(false);
|
||||
vp->Transparency.setValue(90);
|
||||
}
|
||||
}
|
||||
|
||||
ui->pushButtonAddProjFace->setChecked(false);
|
||||
on_pushButtonAddProjFace_clicked();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PartGui::DlgProjectionOnSurface::get_camera_direction(void)
|
||||
{
|
||||
auto mainWindow = Gui::getMainWindow();
|
||||
|
||||
auto mdiObject = dynamic_cast<Gui::View3DInventor*>(mainWindow->activeWindow());
|
||||
if (!mdiObject) return;
|
||||
auto camerRotation = mdiObject->getViewer()->getCameraOrientation();
|
||||
|
||||
SbVec3f lookAt(0, 0, -1);
|
||||
camerRotation.multVec(lookAt, lookAt);
|
||||
|
||||
float valX, valY, valZ;
|
||||
lookAt.getValue(valX, valY, valZ);
|
||||
|
||||
ui->doubleSpinBoxDirX->setValue(valX);
|
||||
ui->doubleSpinBoxDirY->setValue(valY);
|
||||
ui->doubleSpinBoxDirZ->setValue(valZ);
|
||||
}
|
||||
|
||||
void PartGui::DlgProjectionOnSurface::store_current_selected_parts(std::vector<SShapeStore>& iStoreVec, const unsigned int iColor)
|
||||
{
|
||||
App::Document* activeDoc = App::GetApplication().getActiveDocument();
|
||||
if (!activeDoc) return;
|
||||
std::vector<Gui::SelectionObject> selObj = Gui::Selection().getSelectionEx();
|
||||
if (selObj.size())
|
||||
{
|
||||
for (auto it = selObj.begin(); it != selObj.end(); ++it)
|
||||
{
|
||||
auto aPart = dynamic_cast<Part::Feature*>(it->getObject());
|
||||
if (!aPart) continue;
|
||||
|
||||
if (aPart)
|
||||
{
|
||||
SShapeStore currentShapeStore;
|
||||
currentShapeStore.inputShape = aPart->Shape.getShape().getShape();
|
||||
currentShapeStore.partFeature = aPart;
|
||||
currentShapeStore.partName = aPart->getNameInDocument();
|
||||
|
||||
PartGui::ViewProviderPartExt* vp = dynamic_cast<PartGui::ViewProviderPartExt*>(Gui::Application::Instance->getViewProvider(aPart));
|
||||
if (vp)
|
||||
{
|
||||
currentShapeStore.is_selectable = vp->Selectable.getValue();
|
||||
currentShapeStore.transparency = vp->Transparency.getValue();
|
||||
}
|
||||
if (it->getSubNames().size() )
|
||||
{
|
||||
auto parentShape = currentShapeStore.inputShape;
|
||||
for (auto itName = selObj.front().getSubNames().begin(); itName != selObj.front().getSubNames().end(); ++itName)
|
||||
{
|
||||
std::string parentName = aPart->getNameInDocument();
|
||||
auto currentShape = aPart->Shape.getShape().getSubShape(itName->c_str());
|
||||
currentShapeStore.inputShape = currentShape;
|
||||
currentShapeStore.partName = *itName;
|
||||
auto store = store_part_in_vector(currentShapeStore, iStoreVec);
|
||||
higlight_object(aPart, *itName, store, iColor);
|
||||
store_wire_in_vector(currentShapeStore, parentShape, iStoreVec, iColor);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto store = store_part_in_vector(currentShapeStore, iStoreVec);
|
||||
higlight_object(aPart, aPart->Shape.getName(), store, iColor);
|
||||
}
|
||||
Gui::Selection().clearSelection(activeDoc->getName());
|
||||
Gui::Selection().rmvPreselect();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool PartGui::DlgProjectionOnSurface::store_part_in_vector(SShapeStore& iCurrentShape, std::vector<SShapeStore>& iStoreVec)
|
||||
{
|
||||
if (iCurrentShape.inputShape.IsNull()) return false;
|
||||
auto currentType = iCurrentShape.inputShape.ShapeType();
|
||||
for ( auto it = iStoreVec.begin(); it != iStoreVec.end(); ++it)
|
||||
{
|
||||
if ( currentType == TopAbs_FACE )
|
||||
{
|
||||
if (it->aFace.IsSame(iCurrentShape.inputShape))
|
||||
{
|
||||
iStoreVec.erase(it);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if ( currentType == TopAbs_EDGE )
|
||||
{
|
||||
if (it->aEdge.IsSame(iCurrentShape.inputShape))
|
||||
{
|
||||
iStoreVec.erase(it);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (currentType == TopAbs_FACE)
|
||||
{
|
||||
iCurrentShape.aFace = TopoDS::Face(iCurrentShape.inputShape);
|
||||
}
|
||||
else if (currentType == TopAbs_EDGE)
|
||||
{
|
||||
iCurrentShape.aEdge = TopoDS::Edge(iCurrentShape.inputShape);
|
||||
}
|
||||
|
||||
auto valX = ui->doubleSpinBoxDirX->value();
|
||||
auto valY = ui->doubleSpinBoxDirY->value();
|
||||
auto valZ = ui->doubleSpinBoxDirZ->value();
|
||||
|
||||
iCurrentShape.aProjectionDir = gp_Dir(valX, valY, valZ);
|
||||
if ( m_projectionSurfaceVec.size() )
|
||||
{
|
||||
iCurrentShape.surfaceToProject = m_projectionSurfaceVec.front().aFace;
|
||||
}
|
||||
iStoreVec.push_back(iCurrentShape);
|
||||
return true;
|
||||
}
|
||||
|
||||
void PartGui::DlgProjectionOnSurface::create_projection_wire(std::vector<SShapeStore>& iCurrentShape)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (iCurrentShape.empty()) return;
|
||||
for ( auto &itCurrentShape : iCurrentShape )
|
||||
{
|
||||
if (m_projectionSurfaceVec.empty()) continue;;
|
||||
if (itCurrentShape.aProjectedEdgeVec.size()) continue;;
|
||||
if (!itCurrentShape.aProjectedFace.IsNull()) continue;;
|
||||
if (itCurrentShape.aProjectedWireVec.size()) continue;;
|
||||
|
||||
if (!itCurrentShape.aFace.IsNull())
|
||||
{
|
||||
get_all_wire_from_face(itCurrentShape);
|
||||
for (auto itWire : itCurrentShape.aWireVec)
|
||||
{
|
||||
BRepProj_Projection aProjection(itWire, itCurrentShape.surfaceToProject, itCurrentShape.aProjectionDir);
|
||||
auto currentProjection = aProjection.Shape();
|
||||
auto aWire = sort_and_heal_wire(currentProjection, itCurrentShape.surfaceToProject);
|
||||
itCurrentShape.aProjectedWireVec.push_back(aWire);
|
||||
}
|
||||
}
|
||||
else if (!itCurrentShape.aEdge.IsNull())
|
||||
{
|
||||
BRepProj_Projection aProjection(itCurrentShape.aEdge, itCurrentShape.surfaceToProject, itCurrentShape.aProjectionDir);
|
||||
auto currentProjection = aProjection.Shape();
|
||||
for (TopExp_Explorer aExplorer(currentProjection, TopAbs_EDGE); aExplorer.More(); aExplorer.Next())
|
||||
{
|
||||
itCurrentShape.aProjectedEdgeVec.push_back(TopoDS::Edge(aExplorer.Current()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
catch (Standard_Failure)
|
||||
{
|
||||
auto error = Standard_Failure::Caught();
|
||||
std::stringstream ssOcc;
|
||||
error->Print(ssOcc);
|
||||
throw Base::ValueError(ssOcc.str().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
TopoDS_Shape PartGui::DlgProjectionOnSurface::create_compound(const std::vector<SShapeStore>& iShapeVec)
|
||||
{
|
||||
if (iShapeVec.empty()) return TopoDS_Shape();
|
||||
|
||||
TopoDS_Compound aCompound;
|
||||
TopoDS_Builder aBuilder;
|
||||
aBuilder.MakeCompound(aCompound);
|
||||
|
||||
for (auto it : iShapeVec)
|
||||
{
|
||||
if ( m_currentShowType == "edges" )
|
||||
{
|
||||
for (auto it2 : it.aProjectedEdgeVec)
|
||||
{
|
||||
aBuilder.Add(aCompound, it2);
|
||||
}
|
||||
for (auto it2 : it.aProjectedWireVec)
|
||||
{
|
||||
aBuilder.Add(aCompound, it2);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else if ( m_currentShowType == "faces" )
|
||||
{
|
||||
if (it.aProjectedFace.IsNull())
|
||||
{
|
||||
for (auto it2 : it.aProjectedWireVec)
|
||||
{
|
||||
if (!it2.IsNull())
|
||||
{
|
||||
aBuilder.Add(aCompound, it2);
|
||||
}
|
||||
}
|
||||
}
|
||||
else aBuilder.Add(aCompound, it.aProjectedFace);
|
||||
continue;
|
||||
}
|
||||
else if ( m_currentShowType == "all" )
|
||||
{
|
||||
if (!it.aProjectedSolid.IsNull())
|
||||
{
|
||||
aBuilder.Add(aCompound, it.aProjectedSolid);
|
||||
}
|
||||
else if ( !it.aProjectedFace.IsNull() )
|
||||
{
|
||||
aBuilder.Add(aCompound, it.aProjectedFace);
|
||||
}
|
||||
else if (it.aProjectedWireVec.size())
|
||||
{
|
||||
for ( auto itWire : it.aProjectedWireVec )
|
||||
{
|
||||
if ( itWire.IsNull() ) continue;
|
||||
aBuilder.Add(aCompound, itWire);
|
||||
}
|
||||
}
|
||||
else if (it.aProjectedEdgeVec.size())
|
||||
{
|
||||
for (auto itEdge : it.aProjectedEdgeVec)
|
||||
{
|
||||
if (itEdge.IsNull()) continue;
|
||||
aBuilder.Add(aCompound, itEdge);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return aCompound;
|
||||
}
|
||||
|
||||
void PartGui::DlgProjectionOnSurface::show_projected_shapes(const std::vector<SShapeStore>& iShapeStoreVec)
|
||||
{
|
||||
if (!m_projectionObject) return;
|
||||
auto aCompound = create_compound(iShapeStoreVec);
|
||||
if ( aCompound.IsNull() )
|
||||
{
|
||||
App::Document* activeDoc = App::GetApplication().getActiveDocument();
|
||||
if (!activeDoc) return;
|
||||
activeDoc->removeObject(m_projectionObject->getNameInDocument());
|
||||
m_projectionObject = dynamic_cast<Part::Feature*>(activeDoc->addObject("Part::Feature", std::string(m_projectionObjectName.toUtf8()).c_str()));
|
||||
return;
|
||||
}
|
||||
auto currentPlacement = m_projectionObject->Placement.getValue();
|
||||
m_projectionObject->Shape.setValue(aCompound);
|
||||
m_projectionObject->Placement.setValue(currentPlacement);
|
||||
|
||||
//set color
|
||||
PartGui::ViewProviderPartExt* vp = dynamic_cast<PartGui::ViewProviderPartExt*>(Gui::Application::Instance->getViewProvider(m_projectionObject));
|
||||
if (vp)
|
||||
{
|
||||
vp->LineColor.setValue(0x8ae23400);
|
||||
vp->ShapeColor.setValue(0x8ae23400);
|
||||
vp->PointColor.setValue(0x8ae23400);
|
||||
}
|
||||
}
|
||||
|
||||
void PartGui::DlgProjectionOnSurface::disable_ui_elements(const std::vector<QWidget*>& iObjectVec, QWidget* iExceptThis)
|
||||
{
|
||||
for ( auto it : iObjectVec )
|
||||
{
|
||||
if ( !it ) continue;
|
||||
if ( it == iExceptThis ) continue;
|
||||
it->setDisabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
void PartGui::DlgProjectionOnSurface::enable_ui_elements(const std::vector<QWidget*>& iObjectVec, QWidget* iExceptThis)
|
||||
{
|
||||
for (auto it : iObjectVec)
|
||||
{
|
||||
if (!it) continue;
|
||||
if (it == iExceptThis) continue;
|
||||
it->setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
void PartGui::DlgProjectionOnSurface::higlight_object(Part::Feature* iCurrentObject, const std::string& iShapeName, bool iHighlight, const unsigned int iColor)
|
||||
{
|
||||
if (!iCurrentObject) return;
|
||||
auto partenShape = iCurrentObject->Shape.getShape().getShape();
|
||||
auto subShape = iCurrentObject->Shape.getShape().getSubShape(iShapeName.c_str());
|
||||
|
||||
TopoDS_Shape currentShape = subShape;
|
||||
if (subShape.IsNull()) currentShape = partenShape;
|
||||
|
||||
auto currentShapeType = currentShape.ShapeType();
|
||||
TopTools_IndexedMapOfShape anIndices;
|
||||
TopExp::MapShapes(partenShape, currentShapeType, anIndices);
|
||||
if (anIndices.IsEmpty()) return;
|
||||
if (!anIndices.Contains(currentShape)) return;
|
||||
auto index = anIndices.FindIndex(currentShape);
|
||||
|
||||
//set color
|
||||
PartGui::ViewProviderPartExt* vp = dynamic_cast<PartGui::ViewProviderPartExt*>(Gui::Application::Instance->getViewProvider(iCurrentObject));
|
||||
if (vp)
|
||||
{
|
||||
std::vector<App::Color> colors;
|
||||
App::Color defaultColor;
|
||||
if (currentShapeType == TopAbs_FACE)
|
||||
{
|
||||
colors = vp->DiffuseColor.getValues();
|
||||
defaultColor = vp->ShapeColor.getValue();
|
||||
}
|
||||
else if ( currentShapeType == TopAbs_EDGE )
|
||||
{
|
||||
colors = vp->LineColorArray.getValues();
|
||||
defaultColor = vp->LineColor.getValue();
|
||||
}
|
||||
|
||||
if ( colors.size() != anIndices.Extent() )
|
||||
{
|
||||
colors.resize(anIndices.Extent(), defaultColor);
|
||||
}
|
||||
|
||||
if ( iHighlight )
|
||||
{
|
||||
App::Color aColor;
|
||||
aColor.setPackedValue(iColor);
|
||||
colors.at(index - 1) = aColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
colors.at(index - 1) = defaultColor;
|
||||
}
|
||||
if (currentShapeType == TopAbs_FACE)
|
||||
{
|
||||
vp->DiffuseColor.setValues(colors);
|
||||
}
|
||||
else if (currentShapeType == TopAbs_EDGE)
|
||||
{
|
||||
vp->LineColorArray.setValues(colors);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PartGui::DlgProjectionOnSurface::get_all_wire_from_face(SShapeStore& ioCurrentSahpe)
|
||||
{
|
||||
auto outerWire = ShapeAnalysis::OuterWire(ioCurrentSahpe.aFace);
|
||||
ioCurrentSahpe.aWireVec.push_back(outerWire);
|
||||
for (TopExp_Explorer aExplorer(ioCurrentSahpe.aFace, TopAbs_WIRE); aExplorer.More(); aExplorer.Next())
|
||||
{
|
||||
auto currentWire = TopoDS::Wire(aExplorer.Current());
|
||||
if (currentWire.IsSame(outerWire)) continue;
|
||||
ioCurrentSahpe.aWireVec.push_back(currentWire);
|
||||
}
|
||||
}
|
||||
|
||||
void PartGui::DlgProjectionOnSurface::create_projection_face_from_wire(std::vector<SShapeStore>& iCurrentShape)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (iCurrentShape.empty()) return;
|
||||
|
||||
for ( auto &itCurrentShape : iCurrentShape )
|
||||
{
|
||||
if (itCurrentShape.aFace.IsNull()) continue;;
|
||||
if (itCurrentShape.aProjectedWireVec.empty()) continue;;
|
||||
if (!itCurrentShape.aProjectedFace.IsNull()) continue;;
|
||||
|
||||
auto surface = BRep_Tool::Surface(itCurrentShape.surfaceToProject);
|
||||
|
||||
//create a wire of all edges in parametric space on the surface of the face to projected
|
||||
// --> othwerwise BRepBuilderAPI_MakeFace can not make a face from the wire!
|
||||
for (auto itWireVec : itCurrentShape.aProjectedWireVec)
|
||||
{
|
||||
std::vector<const TopoDS_Shape> edgeVec;
|
||||
for (TopExp_Explorer aExplorer(itWireVec, TopAbs_EDGE); aExplorer.More(); aExplorer.Next())
|
||||
{
|
||||
auto currentEdge = TopoDS::Edge(aExplorer.Current());
|
||||
edgeVec.push_back(currentEdge);
|
||||
}
|
||||
if (edgeVec.empty()) continue;
|
||||
|
||||
BRepBuilderAPI_MakeWire aWire;
|
||||
for (auto itEdge : edgeVec)
|
||||
{
|
||||
Standard_Real first, last;
|
||||
auto currentCurve = BRep_Tool::Curve(TopoDS::Edge(itEdge), first, last);
|
||||
// trim the curve, otherwise it can be an infinite one
|
||||
auto trimmedCurve = new Geom_TrimmedCurve(currentCurve, first, last);
|
||||
|
||||
// get parametric space curve
|
||||
auto aCurve = GeomProjLib::Curve2d(trimmedCurve, surface);
|
||||
auto edgeInParametricSpace = BRepBuilderAPI_MakeEdge(aCurve, surface).Edge();
|
||||
ShapeFix_Edge aEdgeRepair;
|
||||
aEdgeRepair.FixAddCurve3d(edgeInParametricSpace);
|
||||
aWire.Add(edgeInParametricSpace);
|
||||
}
|
||||
if (!aWire.IsDone())
|
||||
{
|
||||
std::stringstream errmsg;
|
||||
errmsg << "Cannot create wire in parametric space....: " << aWire.Error() << "\n";
|
||||
Base::Console().Warning(errmsg.str().c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
ShapeFix_Wire aWireRepair(aWire.Wire(), itCurrentShape.surfaceToProject, 0.00001);
|
||||
aWireRepair.FixAddCurve3dMode();
|
||||
aWireRepair.FixAddPCurveMode();
|
||||
aWireRepair.Perform();
|
||||
itCurrentShape.aProjectedWireInParametricSpaceVec.push_back(aWireRepair.Wire());
|
||||
}
|
||||
|
||||
// try to create a face from the wires
|
||||
// the first wire is the outerwire
|
||||
// the following wires are the inside wires
|
||||
BRepBuilderAPI_MakeFace faceMaker;
|
||||
bool first = true;
|
||||
for (auto itWireVec : itCurrentShape.aProjectedWireInParametricSpaceVec)
|
||||
{
|
||||
if (first)
|
||||
{
|
||||
first = false;
|
||||
// change the wire direction, othwerwise no face is created
|
||||
auto currentWire = TopoDS::Wire(itWireVec.Reversed());
|
||||
if (itCurrentShape.surfaceToProject.Orientation() == TopAbs_REVERSED) currentWire = itWireVec;
|
||||
faceMaker = BRepBuilderAPI_MakeFace(surface, currentWire);
|
||||
ShapeFix_Face fix(faceMaker.Face());
|
||||
fix.Perform();
|
||||
auto aFace = fix.Face();
|
||||
BRepCheck_Analyzer aChecker(aFace);
|
||||
if (!aChecker.IsValid())
|
||||
{
|
||||
faceMaker = BRepBuilderAPI_MakeFace(surface, itWireVec);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// make a copy of the current face maker
|
||||
// if the face fails just try again with the copy
|
||||
auto tempCopy = BRepBuilderAPI_MakeFace(faceMaker.Face());
|
||||
faceMaker.Add(TopoDS::Wire(itWireVec.Reversed()));
|
||||
ShapeFix_Face fix(faceMaker.Face());
|
||||
fix.Perform();
|
||||
auto aFace = fix.Face();
|
||||
BRepCheck_Analyzer aChecker(aFace);
|
||||
if (!aChecker.IsValid())
|
||||
{
|
||||
faceMaker = BRepBuilderAPI_MakeFace(tempCopy);
|
||||
faceMaker.Add(TopoDS::Wire(itWireVec));
|
||||
}
|
||||
}
|
||||
}
|
||||
auto doneFlag = faceMaker.IsDone();
|
||||
auto error = faceMaker.Error();
|
||||
itCurrentShape.aProjectedFace = faceMaker.Face();
|
||||
}
|
||||
}
|
||||
catch (Standard_Failure)
|
||||
{
|
||||
auto error = Standard_Failure::Caught();
|
||||
std::stringstream ssOcc;
|
||||
error->Print(ssOcc);
|
||||
throw Base::ValueError(ssOcc.str().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
TopoDS_Wire PartGui::DlgProjectionOnSurface::sort_and_heal_wire(const TopoDS_Shape& iShape, const TopoDS_Face& iFaceToProject)
|
||||
{
|
||||
// try to sort and heal all wires
|
||||
// if the wires are not clean making a face will fail!
|
||||
ShapeAnalysis_FreeBounds shapeAnalyzer;
|
||||
Handle(TopTools_HSequenceOfShape) shapeList = new TopTools_HSequenceOfShape;
|
||||
Handle(TopTools_HSequenceOfShape) aWireHandle;
|
||||
Handle(TopTools_HSequenceOfShape) aWireWireHandle;
|
||||
for (TopExp_Explorer aExplorer(iShape, TopAbs_EDGE); aExplorer.More(); aExplorer.Next())
|
||||
{
|
||||
auto anEdge = TopoDS::Edge(aExplorer.Current());
|
||||
shapeList->Append(TopoDS::Edge(aExplorer.Current()));
|
||||
}
|
||||
shapeAnalyzer.ConnectEdgesToWires(shapeList, 0.0001, false, aWireHandle);
|
||||
shapeAnalyzer.ConnectWiresToWires(aWireHandle, 0.0001, false, aWireWireHandle);
|
||||
if (!aWireWireHandle) return TopoDS_Wire();
|
||||
for (auto it = 1; it <= aWireWireHandle->Length(); ++it)
|
||||
{
|
||||
auto aShape = TopoDS::Wire(aWireWireHandle->Value(it));
|
||||
ShapeFix_Wire aWireRepair(aShape, iFaceToProject, 0.0001);
|
||||
aWireRepair.FixAddCurve3dMode();
|
||||
aWireRepair.FixAddPCurveMode();
|
||||
aWireRepair.Perform();
|
||||
//return aWireRepair.Wire();
|
||||
ShapeFix_Wireframe aWireFramFix(aWireRepair.Wire());
|
||||
auto retVal = aWireFramFix.FixWireGaps();
|
||||
retVal = aWireFramFix.FixSmallEdges();
|
||||
return TopoDS::Wire(aWireFramFix.Shape());
|
||||
}
|
||||
return TopoDS_Wire();
|
||||
}
|
||||
|
||||
void PartGui::DlgProjectionOnSurface::create_face_extrude(std::vector<SShapeStore>& iCurrentShape)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (iCurrentShape.empty()) return;
|
||||
|
||||
for ( auto &itCurrentShape : iCurrentShape )
|
||||
{
|
||||
if (itCurrentShape.aProjectedFace.IsNull()) continue;;
|
||||
auto height = ui->doubleSpinBoxExtrudeHeight->value();
|
||||
if (itCurrentShape.exrudeValue == height) continue;;
|
||||
|
||||
gp_Vec directionToExtrude(itCurrentShape.aProjectionDir.XYZ());
|
||||
directionToExtrude.Reverse();
|
||||
if (height == 0) return;
|
||||
directionToExtrude.Multiply(height);
|
||||
BRepPrimAPI_MakePrism extrude(itCurrentShape.aProjectedFace, directionToExtrude);
|
||||
itCurrentShape.aProjectedSolid = extrude.Shape();
|
||||
itCurrentShape.exrudeValue = height;
|
||||
}
|
||||
}
|
||||
catch (Standard_Failure)
|
||||
{
|
||||
auto error = Standard_Failure::Caught();
|
||||
std::stringstream ssOcc;
|
||||
error->Print(ssOcc);
|
||||
throw Base::ValueError(ssOcc.str().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void PartGui::DlgProjectionOnSurface::store_wire_in_vector(const SShapeStore& iCurrentShape, const TopoDS_Shape& iParentShape, std::vector<SShapeStore>& iStoreVec, const unsigned int iColor)
|
||||
{
|
||||
if (m_currentSelection != "add_wire") return;
|
||||
if (iParentShape.IsNull()) return;
|
||||
if (iCurrentShape.inputShape.IsNull()) return;
|
||||
auto currentType = iCurrentShape.inputShape.ShapeType();
|
||||
if (currentType != TopAbs_EDGE) return;
|
||||
|
||||
std::vector<TopoDS_Wire> aWireVec;
|
||||
for (TopExp_Explorer aExplorer(iParentShape, TopAbs_WIRE); aExplorer.More(); aExplorer.Next())
|
||||
{
|
||||
aWireVec.push_back(TopoDS::Wire(aExplorer.Current()));
|
||||
}
|
||||
|
||||
std::vector<TopoDS_Edge> edgeVec;
|
||||
for ( auto it : aWireVec )
|
||||
{
|
||||
bool edgeExists = false;
|
||||
for (TopExp_Explorer aExplorer(it, TopAbs_EDGE); aExplorer.More(); aExplorer.Next())
|
||||
{
|
||||
auto currentEdge = TopoDS::Edge(aExplorer.Current());
|
||||
edgeVec.push_back(currentEdge);
|
||||
if (currentEdge.IsSame(iCurrentShape.inputShape)) edgeExists = true;
|
||||
}
|
||||
if (edgeExists) break;
|
||||
edgeVec.clear();
|
||||
}
|
||||
|
||||
if (edgeVec.empty()) return;
|
||||
TopTools_IndexedMapOfShape indexMap;
|
||||
TopExp::MapShapes(iParentShape, TopAbs_EDGE, indexMap);
|
||||
if (indexMap.IsEmpty()) return;
|
||||
|
||||
for ( auto it : edgeVec )
|
||||
{
|
||||
if ( it.IsSame(iCurrentShape.inputShape)) continue;
|
||||
if (!indexMap.Contains(it)) return;
|
||||
auto index = indexMap.FindIndex(it);
|
||||
auto newEdgeObject = iCurrentShape;
|
||||
newEdgeObject.inputShape = it;
|
||||
newEdgeObject.partName = "Edge" + std::to_string(index);
|
||||
|
||||
auto store = store_part_in_vector(newEdgeObject, iStoreVec);
|
||||
higlight_object(newEdgeObject.partFeature, newEdgeObject.partName, store, iColor);
|
||||
}
|
||||
}
|
||||
|
||||
void PartGui::DlgProjectionOnSurface::set_xyz_dir_spinbox(QDoubleSpinBox* icurrentSpinBox)
|
||||
{
|
||||
auto currentVal = icurrentSpinBox->value();
|
||||
auto newVal = 0.0;
|
||||
if (currentVal != 1.0 && currentVal != -1.0)
|
||||
{
|
||||
newVal = -1;
|
||||
}
|
||||
else if (currentVal == 1.0)
|
||||
{
|
||||
newVal = -1;
|
||||
}
|
||||
else if (currentVal == -1.0)
|
||||
{
|
||||
newVal = 1;
|
||||
}
|
||||
ui->doubleSpinBoxDirX->setValue(0);
|
||||
ui->doubleSpinBoxDirY->setValue(0);
|
||||
ui->doubleSpinBoxDirZ->setValue(0);
|
||||
icurrentSpinBox->setValue(newVal);
|
||||
}
|
||||
|
||||
void PartGui::DlgProjectionOnSurface::on_pushButtonAddProjFace_clicked()
|
||||
{
|
||||
if (ui->pushButtonAddProjFace->isChecked())
|
||||
{
|
||||
m_currentSelection = "add_projection_surface";
|
||||
disable_ui_elements(m_guiObjectVec, ui->pushButtonAddProjFace);
|
||||
if (!filterFace)
|
||||
{
|
||||
filterFace = new FaceSelection();
|
||||
Gui::Selection().addSelectionGate(filterFace);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_currentSelection = "";
|
||||
enable_ui_elements(m_guiObjectVec, nullptr);
|
||||
Gui::Selection().rmvSelectionGate();
|
||||
filterFace = nullptr;
|
||||
}
|
||||
}
|
||||
void PartGui::DlgProjectionOnSurface::on_radioButtonShowAll_clicked()
|
||||
{
|
||||
m_currentShowType = "all";
|
||||
show_projected_shapes(m_shapeVec);
|
||||
}
|
||||
|
||||
void PartGui::DlgProjectionOnSurface::on_radioButtonFaces_clicked()
|
||||
{
|
||||
m_currentShowType = "faces";
|
||||
show_projected_shapes(m_shapeVec);
|
||||
}
|
||||
|
||||
void PartGui::DlgProjectionOnSurface::on_radioButtonEdges_clicked()
|
||||
{
|
||||
m_currentShowType = "edges";
|
||||
show_projected_shapes(m_shapeVec);
|
||||
}
|
||||
void PartGui::DlgProjectionOnSurface::on_doubleSpinBoxExtrudeHeight_valueChanged(double arg1)
|
||||
{
|
||||
create_face_extrude(m_shapeVec);
|
||||
show_projected_shapes(m_shapeVec);
|
||||
}
|
||||
void PartGui::DlgProjectionOnSurface::on_pushButtonAddWire_clicked()
|
||||
{
|
||||
if (ui->pushButtonAddWire->isChecked())
|
||||
{
|
||||
m_currentSelection = "add_wire";
|
||||
disable_ui_elements(m_guiObjectVec, ui->pushButtonAddWire);
|
||||
if (!filterEdge)
|
||||
{
|
||||
filterEdge = new EdgeSelection();
|
||||
Gui::Selection().addSelectionGate(filterEdge);
|
||||
}
|
||||
ui->radioButtonEdges->setChecked(true);
|
||||
on_radioButtonEdges_clicked();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_currentSelection = "";
|
||||
enable_ui_elements(m_guiObjectVec, nullptr);
|
||||
Gui::Selection().rmvSelectionGate();
|
||||
filterEdge = nullptr;
|
||||
}
|
||||
}
|
||||
void PartGui::DlgProjectionOnSurface::on_doubleSpinBoxSolidDepth_valueChanged(double arg1)
|
||||
{
|
||||
auto valX = ui->doubleSpinBoxDirX->value();
|
||||
auto valY = ui->doubleSpinBoxDirY->value();
|
||||
auto valZ = ui->doubleSpinBoxDirZ->value();
|
||||
|
||||
auto valueToMove = arg1 - m_lastDepthVal;
|
||||
Base::Vector3d vectorToMove(valX, valY, valZ);
|
||||
vectorToMove *= valueToMove;
|
||||
|
||||
auto placment = m_projectionObject->Placement.getValue();
|
||||
placment.move(vectorToMove);
|
||||
m_projectionObject->Placement.setValue(placment);
|
||||
|
||||
m_lastDepthVal = ui->doubleSpinBoxSolidDepth->value();
|
||||
}
|
||||
// ---------------------------------------
|
||||
|
||||
TaskProjectionOnSurface::TaskProjectionOnSurface()
|
||||
{
|
||||
widget = new DlgProjectionOnSurface();
|
||||
taskbox = new Gui::TaskView::TaskBox(
|
||||
Gui::BitmapFactory().pixmap("Part_Extrude"),
|
||||
Gui::BitmapFactory().pixmap("Part_ProjectionOnSurface"),
|
||||
widget->windowTitle(), true, 0);
|
||||
taskbox->groupLayout()->addWidget(widget);
|
||||
Content.push_back(taskbox);
|
||||
@@ -38,8 +972,9 @@ TaskProjectionOnSurface::~TaskProjectionOnSurface()
|
||||
|
||||
bool TaskProjectionOnSurface::accept()
|
||||
{
|
||||
widget->accept();
|
||||
return (widget->result() == QDialog::Accepted);
|
||||
return true;
|
||||
widget->apply();
|
||||
//return (widget->result() == QDialog::Accepted);
|
||||
}
|
||||
|
||||
bool TaskProjectionOnSurface::reject()
|
||||
@@ -52,7 +987,7 @@ void TaskProjectionOnSurface::clicked(int id)
|
||||
{
|
||||
if (id == QDialogButtonBox::Apply) {
|
||||
try {
|
||||
//widget->apply();
|
||||
widget->apply();
|
||||
}
|
||||
catch (Base::AbortException&) {
|
||||
|
||||
@@ -60,3 +995,6 @@ void TaskProjectionOnSurface::clicked(int id)
|
||||
}
|
||||
}
|
||||
|
||||
#include "moc_DlgProjectionOnSurface.cpp"
|
||||
|
||||
|
||||
|
||||
@@ -1,33 +1,141 @@
|
||||
#ifndef DLGPROJECTIONONSURFACE_H
|
||||
#define DLGPROJECTIONONSURFACE_H
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2019 Manuel Apeltauer, direkt cnc-systeme GmbH *
|
||||
* *
|
||||
* 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 *
|
||||
* *
|
||||
***************************************************************************/
|
||||
#ifndef PARTGUI_DLGPROJECTIONONSURFACE_H
|
||||
#define PARTGUI_DLGPROJECTIONONSURFACE_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QWidget>
|
||||
#include <QDoubleSpinBox>
|
||||
|
||||
#include <Gui/TaskView/TaskDialog.h>
|
||||
#include <Gui/TaskView/TaskView.h>
|
||||
|
||||
namespace Ui {
|
||||
}
|
||||
#include "../App/PartFeature.h"
|
||||
|
||||
#include "TopoDS_Shape.hxx"
|
||||
#include "TopoDS_Edge.hxx"
|
||||
#include "TopoDS_Face.hxx"
|
||||
#include "TopoDS_Wire.hxx"
|
||||
|
||||
namespace PartGui {
|
||||
|
||||
class Ui_DlgProjectionOnSurface;
|
||||
|
||||
class DlgProjectionOnSurface : public QDialog
|
||||
namespace Ui {
|
||||
class DlgProjectionOnSurface;
|
||||
}
|
||||
|
||||
class DlgProjectionOnSurface : public QWidget, public Gui::SelectionObserver
|
||||
{
|
||||
//Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DlgProjectionOnSurface(QWidget *parent = 0);
|
||||
~DlgProjectionOnSurface();
|
||||
|
||||
void apply(void);
|
||||
void reject(void);
|
||||
|
||||
private Q_SLOTS:
|
||||
|
||||
void on_pushButtonAddFace_clicked();
|
||||
void on_pushButtonAddEdge_clicked();
|
||||
void on_pushButtonGetCurrentCamDir_clicked();
|
||||
void on_pushButtonDirX_clicked();
|
||||
void on_pushButtonDirY_clicked();
|
||||
void on_pushButtonDirZ_clicked();
|
||||
void on_pushButtonAddProjFace_clicked();
|
||||
void on_radioButtonShowAll_clicked();
|
||||
void on_radioButtonFaces_clicked();
|
||||
void on_radioButtonEdges_clicked();
|
||||
void on_doubleSpinBoxExtrudeHeight_valueChanged(double arg1);
|
||||
void on_pushButtonAddWire_clicked();
|
||||
void on_doubleSpinBoxSolidDepth_valueChanged(double arg1);
|
||||
|
||||
private:
|
||||
Ui_DlgProjectionOnSurface*ui;
|
||||
|
||||
struct SShapeStore
|
||||
{
|
||||
TopoDS_Shape inputShape;
|
||||
TopoDS_Face surfaceToProject;
|
||||
gp_Dir aProjectionDir;
|
||||
TopoDS_Face aFace;
|
||||
TopoDS_Edge aEdge;
|
||||
std::vector<TopoDS_Wire> aWireVec;
|
||||
std::vector<TopoDS_Wire> aProjectedWireVec;
|
||||
std::vector<TopoDS_Edge> aProjectedEdgeVec;
|
||||
std::vector<TopoDS_Wire> aProjectedWireInParametricSpaceVec;
|
||||
TopoDS_Face aProjectedFace;
|
||||
TopoDS_Shape aProjectedSolid;
|
||||
Part::Feature* partFeature;
|
||||
std::string partName;
|
||||
bool is_selectable;
|
||||
long transparency;
|
||||
float exrudeValue;
|
||||
};
|
||||
|
||||
//from Gui::SelectionObserver
|
||||
virtual void onSelectionChanged(const Gui::SelectionChanges& msg);
|
||||
|
||||
|
||||
void get_camera_direction(void);
|
||||
void store_current_selected_parts(std::vector<SShapeStore>& iStoreVec, const unsigned int iColor);
|
||||
bool store_part_in_vector(SShapeStore& iCurrentShape, std::vector<SShapeStore>& iStoreVec);
|
||||
void create_projection_wire(std::vector<SShapeStore>& iCurrentShape);
|
||||
TopoDS_Shape create_compound(const std::vector<SShapeStore>& iShapeVec);
|
||||
void show_projected_shapes(const std::vector<SShapeStore>& iShapeStoreVec);
|
||||
void disable_ui_elements(const std::vector<QWidget*>& iObjectVec, QWidget* iExceptThis);
|
||||
void enable_ui_elements(const std::vector<QWidget*>& iObjectVec, QWidget* iExceptThis);
|
||||
void higlight_object(Part::Feature* iCurrentObject, const std::string& iShapeName, bool iHighlight, const unsigned int iColor);
|
||||
void get_all_wire_from_face(SShapeStore& ioCurrentSahpe);
|
||||
void create_projection_face_from_wire(std::vector<SShapeStore>& iCurrentShape);
|
||||
TopoDS_Wire sort_and_heal_wire(const TopoDS_Shape& iShape, const TopoDS_Face& iFaceToProject);
|
||||
void create_face_extrude(std::vector<SShapeStore>& iCurrentShape);
|
||||
void store_wire_in_vector(const SShapeStore& iCurrentShape, const TopoDS_Shape& iParentShape, std::vector<SShapeStore>& iStoreVec, const unsigned int iColor);
|
||||
void set_xyz_dir_spinbox(QDoubleSpinBox* icurrentSpinBox);
|
||||
|
||||
private:
|
||||
Ui::DlgProjectionOnSurface *ui;
|
||||
std::vector<SShapeStore> m_shapeVec;
|
||||
std::vector<SShapeStore> m_projectionSurfaceVec;
|
||||
|
||||
std::string m_currentSelection;
|
||||
std::string m_currentShowType;
|
||||
|
||||
std::vector<QWidget*> m_guiObjectVec;
|
||||
|
||||
const QString m_projectionObjectName;
|
||||
Part::Feature* m_projectionObject;
|
||||
float m_lastDepthVal;
|
||||
|
||||
class EdgeSelection;
|
||||
EdgeSelection* filterEdge;
|
||||
|
||||
class FaceSelection;
|
||||
FaceSelection* filterFace;
|
||||
};
|
||||
|
||||
class TaskProjectionOnSurface : public Gui::TaskView::TaskDialog
|
||||
{
|
||||
//Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TaskProjectionOnSurface();
|
||||
@@ -40,7 +148,7 @@ public:
|
||||
|
||||
virtual QDialogButtonBox::StandardButtons getStandardButtons() const
|
||||
{
|
||||
return QDialogButtonBox::Ok | QDialogButtonBox::Apply | QDialogButtonBox::Close;
|
||||
return QDialogButtonBox::Ok | QDialogButtonBox::Close;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -48,5 +156,6 @@ private:
|
||||
Gui::TaskView::TaskBox* taskbox;
|
||||
};
|
||||
|
||||
|
||||
} // namespace PartGui
|
||||
#endif // DLGPROJECTIONONSURFACE_H
|
||||
#endif // PARTGUI_DLGPROJECTIONONSURFACE_H
|
||||
|
||||
@@ -1,31 +1,241 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>DlgProjectionOnSurface</class>
|
||||
<widget class="QDialog" name="DlgProjectionOnSurface">
|
||||
<class>PartGui::DlgProjectionOnSurface</class>
|
||||
<widget class="QWidget" name="PartGui::DlgProjectionOnSurface">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
<height>764</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<widget class="QPushButton" name="pushButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>180</x>
|
||||
<y>120</y>
|
||||
<width>75</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>PushButton</string>
|
||||
</property>
|
||||
</widget>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButtonAddProjFace">
|
||||
<property name="text">
|
||||
<string>Select projection surface</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButtonAddFace">
|
||||
<property name="text">
|
||||
<string>Add face</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButtonAddWire">
|
||||
<property name="text">
|
||||
<string>Add wire</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButtonAddEdge">
|
||||
<property name="text">
|
||||
<string>Add edge</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radioButtonShowAll">
|
||||
<property name="text">
|
||||
<string>Show all</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radioButtonFaces">
|
||||
<property name="text">
|
||||
<string>Show faces</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radioButtonEdges">
|
||||
<property name="text">
|
||||
<string>Show Edges</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<item>
|
||||
<widget class="QLabel" name="labelExtrudeHeigth">
|
||||
<property name="text">
|
||||
<string>Extrude height</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBoxExtrudeHeight">
|
||||
<property name="maximum">
|
||||
<double>999.000000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>10.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||
<item>
|
||||
<widget class="QLabel" name="labelDepth">
|
||||
<property name="text">
|
||||
<string>Solid depth</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBoxSolidDepth">
|
||||
<property name="minimum">
|
||||
<double>-999.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>999.000000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>0.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBoxDir">
|
||||
<property name="title">
|
||||
<string>Direction</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButtonGetCurrentCamDir">
|
||||
<property name="text">
|
||||
<string>Get current camera direction</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButtonDirX">
|
||||
<property name="text">
|
||||
<string>X:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBoxDirX">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>-1.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButtonDirY">
|
||||
<property name="text">
|
||||
<string>Y:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBoxDirY">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>-1.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButtonDirZ">
|
||||
<property name="text">
|
||||
<string>Z:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBoxDirZ">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>-1.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
|
||||
@@ -74,6 +74,7 @@
|
||||
<file>icons/Part_JoinCutout.svg</file>
|
||||
<file>icons/Part_JoinEmbed.svg</file>
|
||||
<file>icons/PartWorkbench.svg</file>
|
||||
<file>icons/Part_ProjectionOnSurface.svg</file>
|
||||
<file>translations/Part_af.qm</file>
|
||||
<file>translations/Part_de.qm</file>
|
||||
<file>translations/Part_fi.qm</file>
|
||||
|
||||
346
src/Mod/Part/Gui/Resources/icons/Part_ProjectionOnSurface.svg
Normal file
346
src/Mod/Part/Gui/Resources/icons/Part_ProjectionOnSurface.svg
Normal file
@@ -0,0 +1,346 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="64"
|
||||
height="64"
|
||||
viewBox="0 0 16.933333 16.933334"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
inkscape:version="0.92.1 r15371"
|
||||
sodipodi:docname="Part_ProjectionOnSurface.svg"
|
||||
inkscape:label="Gear Proj">
|
||||
<defs
|
||||
id="defs2">
|
||||
<linearGradient
|
||||
id="linearGradient3864-9">
|
||||
<stop
|
||||
style="stop-color:#204a87;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop6175" />
|
||||
<stop
|
||||
style="stop-color:#729fcf;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop6177" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3864">
|
||||
<stop
|
||||
style="stop-color:#71b2f8;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3866" />
|
||||
<stop
|
||||
style="stop-color:#002795;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3868" />
|
||||
</linearGradient>
|
||||
<inkscape:perspective
|
||||
id="perspective2988"
|
||||
inkscape:persp3d-origin="32 : 21.333333 : 1"
|
||||
inkscape:vp_z="64 : 32 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 32 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<linearGradient
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="40"
|
||||
x2="20"
|
||||
y1="55.717518"
|
||||
x1="22.116516"
|
||||
id="linearGradient3773"
|
||||
xlink:href="#linearGradient3767"
|
||||
inkscape:collect="always"
|
||||
gradientTransform="matrix(1,0,0,0.80043488,-0.21205357,1.3620882)" />
|
||||
<linearGradient
|
||||
id="linearGradient3767"
|
||||
inkscape:collect="always">
|
||||
<stop
|
||||
id="stop3769"
|
||||
offset="0"
|
||||
style="stop-color:#3465a4;stop-opacity:1" />
|
||||
<stop
|
||||
id="stop3771"
|
||||
offset="1"
|
||||
style="stop-color:#729fcf;stop-opacity:1" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="38"
|
||||
x2="50"
|
||||
y1="51.179787"
|
||||
x1="53.896763"
|
||||
id="linearGradient3783"
|
||||
xlink:href="#linearGradient3777"
|
||||
inkscape:collect="always"
|
||||
gradientTransform="translate(-0.178571,-10.928571)" />
|
||||
<linearGradient
|
||||
id="linearGradient3777"
|
||||
inkscape:collect="always">
|
||||
<stop
|
||||
id="stop3779"
|
||||
offset="0"
|
||||
style="stop-color:#204a87;stop-opacity:1" />
|
||||
<stop
|
||||
id="stop3781"
|
||||
offset="1"
|
||||
style="stop-color:#3465a4;stop-opacity:1" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3767"
|
||||
id="linearGradient5871"
|
||||
x1="44.663254"
|
||||
y1="66.59771"
|
||||
x2="80.450974"
|
||||
y2="66.59771"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(-42.769166,-23.920078)" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3777"
|
||||
id="linearGradient5903"
|
||||
x1="44.690838"
|
||||
y1="39.061024"
|
||||
x2="70.759598"
|
||||
y2="39.061024"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(-6.3392858,1.0267858)" />
|
||||
<linearGradient
|
||||
id="linearGradient3682">
|
||||
<stop
|
||||
id="stop3684"
|
||||
offset="0"
|
||||
style="stop-color:#ff6d0f;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3686"
|
||||
offset="1"
|
||||
style="stop-color:#ff1000;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<inkscape:perspective
|
||||
id="perspective3148"
|
||||
inkscape:persp3d-origin="32 : 21.333333 : 1"
|
||||
inkscape:vp_z="64 : 32 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 32 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<linearGradient
|
||||
id="linearGradient3864-9-4">
|
||||
<stop
|
||||
id="stop3866-1"
|
||||
offset="0"
|
||||
style="stop-color:#204a87;stop-opacity:1" />
|
||||
<stop
|
||||
id="stop3868-1"
|
||||
offset="1"
|
||||
style="stop-color:#729fcf;stop-opacity:1" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3682-0">
|
||||
<stop
|
||||
style="stop-color:#a40000;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop3684-0" />
|
||||
<stop
|
||||
style="stop-color:#ef2929;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop3686-0" />
|
||||
</linearGradient>
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 32 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="64 : 32 : 1"
|
||||
inkscape:persp3d-origin="32 : 21.333333 : 1"
|
||||
id="perspective3148-5" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3682-0-6"
|
||||
id="radialGradient3817-5-3"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.2361257,0.30001695,-0.83232803,3.3883821,-499.9452,-167.33108)"
|
||||
cx="270.58316"
|
||||
cy="33.899986"
|
||||
fx="270.58316"
|
||||
fy="33.899986"
|
||||
r="19.571428" />
|
||||
<linearGradient
|
||||
id="linearGradient3682-0-6">
|
||||
<stop
|
||||
style="stop-color:#ff390f;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop3684-0-7" />
|
||||
<stop
|
||||
style="stop-color:#ff1000;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3686-0-5" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="40"
|
||||
x2="20"
|
||||
y1="55.717518"
|
||||
x1="22.116516"
|
||||
id="linearGradient3773-8"
|
||||
xlink:href="#linearGradient3767"
|
||||
inkscape:collect="always"
|
||||
gradientTransform="matrix(0.2719906,0,0,0.21771077,4.1098594,-0.60061144)" />
|
||||
<inkscape:perspective
|
||||
id="perspective2988-3"
|
||||
inkscape:persp3d-origin="32 : 21.333333 : 1"
|
||||
inkscape:vp_z="64 : 32 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 32 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<linearGradient
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="38"
|
||||
x2="50"
|
||||
y1="51.179787"
|
||||
x1="53.896763"
|
||||
id="linearGradient3783-0"
|
||||
xlink:href="#linearGradient3777"
|
||||
inkscape:collect="always"
|
||||
gradientTransform="matrix(0.39506609,0,0,0.39506609,-0.01269431,-5.8114314)" />
|
||||
<linearGradient
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="40"
|
||||
x2="20"
|
||||
y1="55.717518"
|
||||
x1="22.116516"
|
||||
id="linearGradient3773-0"
|
||||
xlink:href="#linearGradient3767"
|
||||
inkscape:collect="always"
|
||||
gradientTransform="matrix(0.39506609,0,0,0.39506609,-0.01269431,-5.8114314)" />
|
||||
<inkscape:perspective
|
||||
id="perspective3148-9"
|
||||
inkscape:persp3d-origin="32 : 21.333333 : 1"
|
||||
inkscape:vp_z="64 : 32 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 32 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 32 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="64 : 32 : 1"
|
||||
inkscape:persp3d-origin="32 : 21.333333 : 1"
|
||||
id="perspective3148-5-0" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3682-0-6"
|
||||
id="radialGradient3817-5-3-3"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.2361257,0.30001695,-0.83232803,3.3883821,-499.9452,-167.33108)"
|
||||
cx="270.58316"
|
||||
cy="33.899986"
|
||||
fx="270.58316"
|
||||
fy="33.899986"
|
||||
r="19.571428" />
|
||||
<linearGradient
|
||||
gradientTransform="matrix(0.21275462,0,0,0.16272468,50.684307,3.2886466)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="7.7114096"
|
||||
x2="-211.40184"
|
||||
y1="68.841812"
|
||||
x1="-206.69949"
|
||||
id="linearGradient3806"
|
||||
xlink:href="#linearGradient4066"
|
||||
inkscape:collect="always" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient4066">
|
||||
<stop
|
||||
style="stop-color:#4e9a06;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop4068" />
|
||||
<stop
|
||||
style="stop-color:#8ae234;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop4070" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="7.919596"
|
||||
inkscape:cx="-19.036936"
|
||||
inkscape:cy="23.646719"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer8"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1096"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
units="px" />
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer7"
|
||||
inkscape:label="Solid"
|
||||
transform="matrix(1.1184437,-0.25664164,0.01996106,1.4775748,-1.0512274,-7.2671715)">
|
||||
<path
|
||||
sodipodi:nodetypes="ccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path2993"
|
||||
d="M 1.1725043,7.225752 14.604751,9.5961484 24.08634,6.4356185 12.234355,4.8553547 Z"
|
||||
style="fill:#729fcf;stroke:#0b1521;stroke-width:0.79013211;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path2995"
|
||||
d="m 24.08634,6.4356185 v 7.9013225 l -9.481589,3.95066 V 9.5961484 Z"
|
||||
style="fill:url(#linearGradient3783-0);fill-opacity:1;stroke:#0b1521;stroke-width:0.79013211;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1" />
|
||||
<path
|
||||
style="display:inline;overflow:visible;visibility:visible;fill:url(#linearGradient3773-0);fill-opacity:1;fill-rule:evenodd;stroke:#0b1521;stroke-width:0.79013211;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
d="M 1.1725043,7.225752 14.604751,9.5961484 V 18.287601 L 1.1725043,15.917205 Z"
|
||||
id="path3825"
|
||||
sodipodi:nodetypes="ccccc"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3765"
|
||||
d="m 1.9626367,8.1848616 0.00343,7.0792334 11.8554093,2.081525 -0.0034,-7.084964 z"
|
||||
style="fill:none;stroke:#729fcf;stroke-width:0.79013211;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3775"
|
||||
d="m 15.399796,10.162606 -0.0049,6.927603 7.90176,-3.27944 1.44e-4,-6.2686576 z"
|
||||
style="fill:none;stroke:#3465a4;stroke-width:0.79013211;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
</g>
|
||||
<g
|
||||
id="layer8"
|
||||
inkscape:label="F">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccccccccc"
|
||||
id="rect3663-8"
|
||||
d="m 4.4570351,3.9695931 2e-6,11.0952039 3.0013315,-1e-6 V 10.473678 H 10.4597 V 8.1781188 H 7.4583686 V 6.2651527 H 12.460589 V 3.9695931 Z"
|
||||
style="display:inline;overflow:visible;visibility:visible;fill:url(#linearGradient3806);fill-opacity:1;fill-rule:evenodd;stroke:#280000;stroke-width:0.43747175;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 12 KiB |
Reference in New Issue
Block a user