NEW: add text gizmo tool
Signed-off-by: yifan.wu <yifan.wu@bambulab.com> Change-Id: I77fdf64340f580e6baa3260101fa1c6db7a4ab2d (cherry picked from commit 2147c55134b4d9d1018d7e9f4f8d1a4d50c065f6)
This commit is contained in:
parent
65ba9cafb3
commit
b068389d4c
|
@ -0,0 +1,4 @@
|
||||||
|
<svg width="40" height="41" viewBox="0 0 40 41" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.5 5V9.44653H13.3165C13.8704 9.44653 14.3091 9.89686 14.3091 10.4441V35.2513H19.9173V10.4441C19.9173 9.89686 20.3561 9.44653 20.91 9.44653H28.7479V5H5.5ZM4.5 4.9976C4.5 4.45033 4.93873 4 5.49267 4H28.7552C29.3092 4 29.7479 4.45033 29.7479 4.9976V9.44894C29.7479 9.99623 29.3092 10.4465 28.7552 10.4465H20.9173V35.2537C20.9173 35.8009 20.4786 36.2513 19.9247 36.2513H14.3018C13.7478 36.2513 13.3091 35.8009 13.3091 35.2537V10.4465H5.49267C4.93875 10.4465 4.5 9.99623 4.5 9.44894V4.9976Z" fill="#00AE42"/>
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M30.6779 23.6992C30.0689 23.6992 29.3177 23.7852 28.4197 23.9751L28.4182 23.9754C27.6749 24.1302 27.073 24.3232 26.6099 24.5434V26.109C27.7461 25.4864 28.9492 25.171 30.2173 25.171C30.9889 25.171 31.6598 25.349 32.1511 25.782C32.6487 26.2205 32.8833 26.8506 32.9229 27.5858L32.9231 27.5891C32.9414 27.979 32.6449 28.2899 32.2969 28.3401L32.2928 28.3407L29.1514 28.7677C29.1511 28.7678 29.1507 28.7678 29.1504 28.7679C27.8225 28.9541 26.8967 29.3651 26.305 29.9484C25.7239 30.5211 25.4104 31.3138 25.4104 32.3885C25.4104 33.4226 25.7167 34.1844 26.2947 34.7368L26.2961 34.7381C26.8746 35.2952 27.6665 35.5935 28.7179 35.5935C30.1353 35.5935 31.1886 34.9959 31.9296 33.7501L32.075 33.5057H32.9022V35.296H35.2866V28.3699C35.2866 26.7229 34.8797 25.5789 34.1537 24.8439C33.4288 24.1101 32.302 23.6992 30.6779 23.6992ZM28.2136 22.9965C29.1574 22.797 29.9803 22.6992 30.6779 22.6992C32.4595 22.6992 33.8871 23.1511 34.8652 24.1412C35.8421 25.1302 36.2866 26.5716 36.2866 28.3699V35.5526C36.2866 35.9594 35.9603 36.296 35.5456 36.296H32.6432C32.2285 36.296 31.9022 35.9594 31.9022 35.5526V35.3882C31.0603 36.1882 29.9911 36.5935 28.7179 36.5935C27.4669 36.5935 26.4062 36.2321 25.6032 35.4591C24.7893 34.681 24.4104 33.6366 24.4104 32.3885C24.4104 31.1051 24.793 30.0346 25.603 29.2362C26.4021 28.4485 27.5618 27.9807 29.0127 27.7774L29.0147 27.7771L31.8992 27.385C31.8383 26.975 31.6887 26.7074 31.4899 26.5322C31.2462 26.3175 30.8488 26.171 30.2173 26.171C28.9832 26.171 27.8162 26.5148 26.7025 27.214L26.7006 27.2152C26.2174 27.5155 25.6099 27.1537 25.6099 26.6013V24.3729C25.6099 24.1204 25.7428 23.8699 25.9835 23.7389L25.9899 23.7355C26.5799 23.4256 27.3295 23.1807 28.2136 22.9965ZM32.929 29.3587V30.8038C32.929 31.6881 32.6556 32.4555 32.0923 33.0761C31.523 33.7034 30.7925 34.019 29.9281 34.019C29.3134 34.019 28.7591 33.8526 28.3341 33.4677C27.9073 33.0812 27.7038 32.5675 27.7038 31.9829C27.7038 31.3652 27.9077 30.8262 28.349 30.4241C28.7742 30.0367 29.3686 29.8233 30.0649 29.7295L30.0674 29.7292L32.929 29.3587ZM30.1984 30.7206C30.1979 30.7207 30.1975 30.7207 30.1971 30.7208C29.6089 30.8001 29.2398 30.9653 29.0225 31.1633C28.8212 31.3466 28.7038 31.6 28.7038 31.9829C28.7038 32.3177 28.8109 32.5504 29.0053 32.7264C29.2015 32.9041 29.4933 33.019 29.9281 33.019C30.5204 33.019 30.9787 32.8153 31.3519 32.4041C31.7311 31.9863 31.929 31.4663 31.929 30.8038V30.4965L30.1984 30.7206Z" fill="#262E30"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 3.0 KiB |
|
@ -315,7 +315,6 @@ set(lisbslic3r_sources
|
||||||
SLA/Clustering.hpp
|
SLA/Clustering.hpp
|
||||||
SLA/Clustering.cpp
|
SLA/Clustering.cpp
|
||||||
SLA/ReprojectPointsOnMesh.hpp
|
SLA/ReprojectPointsOnMesh.hpp
|
||||||
|
|
||||||
Arachne/BeadingStrategy/BeadingStrategy.hpp
|
Arachne/BeadingStrategy/BeadingStrategy.hpp
|
||||||
Arachne/BeadingStrategy/BeadingStrategy.cpp
|
Arachne/BeadingStrategy/BeadingStrategy.cpp
|
||||||
Arachne/BeadingStrategy/BeadingStrategyFactory.hpp
|
Arachne/BeadingStrategy/BeadingStrategyFactory.hpp
|
||||||
|
@ -356,6 +355,8 @@ set(lisbslic3r_sources
|
||||||
Arachne/SkeletalTrapezoidationJoint.hpp
|
Arachne/SkeletalTrapezoidationJoint.hpp
|
||||||
Arachne/WallToolPaths.hpp
|
Arachne/WallToolPaths.hpp
|
||||||
Arachne/WallToolPaths.cpp
|
Arachne/WallToolPaths.cpp
|
||||||
|
Shape/TextShape.hpp
|
||||||
|
Shape/TextShape.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
|
|
|
@ -0,0 +1,203 @@
|
||||||
|
#include "../libslic3r.h"
|
||||||
|
#include "../Model.hpp"
|
||||||
|
#include "../TriangleMesh.hpp"
|
||||||
|
|
||||||
|
#include "TextShape.hpp"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "Standard_TypeDef.hxx"
|
||||||
|
#include "STEPCAFControl_Reader.hxx"
|
||||||
|
#include "BRepMesh_IncrementalMesh.hxx"
|
||||||
|
#include "Interface_Static.hxx"
|
||||||
|
#include "XCAFDoc_DocumentTool.hxx"
|
||||||
|
#include "XCAFDoc_ShapeTool.hxx"
|
||||||
|
#include "XCAFApp_Application.hxx"
|
||||||
|
#include "TopoDS_Solid.hxx"
|
||||||
|
#include "TopoDS_Compound.hxx"
|
||||||
|
#include "TopoDS_Builder.hxx"
|
||||||
|
#include "TopoDS.hxx"
|
||||||
|
#include "TDataStd_Name.hxx"
|
||||||
|
#include "BRepBuilderAPI_Transform.hxx"
|
||||||
|
#include "TopExp_Explorer.hxx"
|
||||||
|
#include "TopExp_Explorer.hxx"
|
||||||
|
#include "BRep_Tool.hxx"
|
||||||
|
#include "Font_BRepFont.hxx"
|
||||||
|
#include "Font_BRepTextBuilder.hxx"
|
||||||
|
#include "BRepPrimAPI_MakePrism.hxx"
|
||||||
|
#include "Font_FontMgr.hxx"
|
||||||
|
|
||||||
|
namespace Slic3r {
|
||||||
|
|
||||||
|
std::vector<std::string> init_occt_fonts()
|
||||||
|
{
|
||||||
|
std::vector<std::string> stdFontNames;
|
||||||
|
|
||||||
|
Handle(Font_FontMgr) aFontMgr = Font_FontMgr::GetInstance();
|
||||||
|
aFontMgr->InitFontDataBase();
|
||||||
|
|
||||||
|
TColStd_SequenceOfHAsciiString availFontNames;
|
||||||
|
aFontMgr->GetAvailableFontsNames(availFontNames);
|
||||||
|
stdFontNames.reserve(availFontNames.Size());
|
||||||
|
|
||||||
|
for (auto afn : availFontNames)
|
||||||
|
stdFontNames.push_back(afn->ToCString());
|
||||||
|
|
||||||
|
return stdFontNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool TextToBRep(const char* text, const char* font, const float theTextHeight, Font_FontAspect& theFontAspect, TopoDS_Shape& theShape)
|
||||||
|
{
|
||||||
|
Standard_Integer anArgIt = 1;
|
||||||
|
Standard_CString aName = "text_shape";
|
||||||
|
Standard_CString aText = text;
|
||||||
|
|
||||||
|
Font_BRepFont aFont;
|
||||||
|
//TCollection_AsciiString aFontName("Courier");
|
||||||
|
TCollection_AsciiString aFontName(font);
|
||||||
|
Standard_Real aTextHeight = theTextHeight;
|
||||||
|
Font_FontAspect aFontAspect = theFontAspect;
|
||||||
|
Standard_Boolean anIsCompositeCurve = Standard_False;
|
||||||
|
gp_Ax3 aPenAx3(gp::XOY());
|
||||||
|
gp_Dir aNormal(0.0, 0.0, 1.0);
|
||||||
|
gp_Dir aDirection(1.0, 0.0, 0.0);
|
||||||
|
gp_Pnt aPenLoc;
|
||||||
|
|
||||||
|
Graphic3d_HorizontalTextAlignment aHJustification = Graphic3d_HTA_LEFT;
|
||||||
|
Graphic3d_VerticalTextAlignment aVJustification = Graphic3d_VTA_BOTTOM;
|
||||||
|
Font_StrictLevel aStrictLevel = Font_StrictLevel_Any;
|
||||||
|
|
||||||
|
aFont.SetCompositeCurveMode(anIsCompositeCurve);
|
||||||
|
if (!aFont.FindAndInit(aFontName.ToCString(), aFontAspect, aTextHeight, aStrictLevel))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
aPenAx3 = gp_Ax3(aPenLoc, aNormal, aDirection);
|
||||||
|
|
||||||
|
Font_BRepTextBuilder aBuilder;
|
||||||
|
theShape = aBuilder.Perform(aFont, aText, aPenAx3, aHJustification, aVJustification);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool Prism(const TopoDS_Shape& theBase, const float thickness, TopoDS_Shape& theSolid)
|
||||||
|
{
|
||||||
|
if (theBase.IsNull()) return false;
|
||||||
|
|
||||||
|
gp_Vec V(0.f, 0.f, thickness);
|
||||||
|
BRepPrimAPI_MakePrism* Prism = new BRepPrimAPI_MakePrism(theBase, V, Standard_False);
|
||||||
|
|
||||||
|
theSolid = Prism->Shape();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MakeMesh(TopoDS_Shape& theSolid, TriangleMesh& theMesh)
|
||||||
|
{
|
||||||
|
const double STEP_TRANS_CHORD_ERROR = 0.005;
|
||||||
|
const double STEP_TRANS_ANGLE_RES = 1;
|
||||||
|
|
||||||
|
BRepMesh_IncrementalMesh mesh(theSolid, STEP_TRANS_CHORD_ERROR, false, STEP_TRANS_ANGLE_RES, true);
|
||||||
|
int aNbNodes = 0;
|
||||||
|
int aNbTriangles = 0;
|
||||||
|
for (TopExp_Explorer anExpSF(theSolid, TopAbs_FACE); anExpSF.More(); anExpSF.Next()) {
|
||||||
|
TopLoc_Location aLoc;
|
||||||
|
Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation(TopoDS::Face(anExpSF.Current()), aLoc);
|
||||||
|
if (!aTriangulation.IsNull()) {
|
||||||
|
aNbNodes += aTriangulation->NbNodes();
|
||||||
|
aNbTriangles += aTriangulation->NbTriangles();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stl_file stl;
|
||||||
|
stl.stats.type = inmemory;
|
||||||
|
stl.stats.number_of_facets = (uint32_t)aNbTriangles;
|
||||||
|
stl.stats.original_num_facets = stl.stats.number_of_facets;
|
||||||
|
stl_allocate(&stl);
|
||||||
|
|
||||||
|
std::vector<Vec3f> points;
|
||||||
|
points.reserve(aNbNodes);
|
||||||
|
//BBS: count faces missing triangulation
|
||||||
|
Standard_Integer aNbFacesNoTri = 0;
|
||||||
|
//BBS: fill temporary triangulation
|
||||||
|
Standard_Integer aNodeOffset = 0;
|
||||||
|
Standard_Integer aTriangleOffet = 0;
|
||||||
|
for (TopExp_Explorer anExpSF(theSolid, TopAbs_FACE); anExpSF.More(); anExpSF.Next()) {
|
||||||
|
const TopoDS_Shape& aFace = anExpSF.Current();
|
||||||
|
TopLoc_Location aLoc;
|
||||||
|
Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation(TopoDS::Face(aFace), aLoc);
|
||||||
|
if (aTriangulation.IsNull()) {
|
||||||
|
++aNbFacesNoTri;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
//BBS: copy nodes
|
||||||
|
gp_Trsf aTrsf = aLoc.Transformation();
|
||||||
|
for (Standard_Integer aNodeIter = 1; aNodeIter <= aTriangulation->NbNodes(); ++aNodeIter) {
|
||||||
|
gp_Pnt aPnt = aTriangulation->Node(aNodeIter);
|
||||||
|
aPnt.Transform(aTrsf);
|
||||||
|
points.emplace_back(std::move(Vec3f(aPnt.X(), aPnt.Y(), aPnt.Z())));
|
||||||
|
}
|
||||||
|
//BBS: copy triangles
|
||||||
|
const TopAbs_Orientation anOrientation = anExpSF.Current().Orientation();
|
||||||
|
for (Standard_Integer aTriIter = 1; aTriIter <= aTriangulation->NbTriangles(); ++aTriIter) {
|
||||||
|
Poly_Triangle aTri = aTriangulation->Triangle(aTriIter);
|
||||||
|
|
||||||
|
Standard_Integer anId[3];
|
||||||
|
aTri.Get(anId[0], anId[1], anId[2]);
|
||||||
|
if (anOrientation == TopAbs_REVERSED) {
|
||||||
|
//BBS: swap 1, 2.
|
||||||
|
Standard_Integer aTmpIdx = anId[1];
|
||||||
|
anId[1] = anId[2];
|
||||||
|
anId[2] = aTmpIdx;
|
||||||
|
}
|
||||||
|
//BBS: Update nodes according to the offset.
|
||||||
|
anId[0] += aNodeOffset;
|
||||||
|
anId[1] += aNodeOffset;
|
||||||
|
anId[2] += aNodeOffset;
|
||||||
|
//BBS: save triangles facets
|
||||||
|
stl_facet facet;
|
||||||
|
facet.vertex[0] = points[anId[0] - 1].cast<float>();
|
||||||
|
facet.vertex[1] = points[anId[1] - 1].cast<float>();
|
||||||
|
facet.vertex[2] = points[anId[2] - 1].cast<float>();
|
||||||
|
facet.extra[0] = 0;
|
||||||
|
facet.extra[1] = 0;
|
||||||
|
stl_normal normal;
|
||||||
|
stl_calculate_normal(normal, &facet);
|
||||||
|
stl_normalize_vector(normal);
|
||||||
|
facet.normal = normal;
|
||||||
|
stl.facet_start[aTriangleOffet + aTriIter - 1] = facet;
|
||||||
|
}
|
||||||
|
|
||||||
|
aNodeOffset += aTriangulation->NbNodes();
|
||||||
|
aTriangleOffet += aTriangulation->NbTriangles();
|
||||||
|
}
|
||||||
|
|
||||||
|
theMesh.from_stl(stl);
|
||||||
|
}
|
||||||
|
|
||||||
|
void load_text_shape(const char*text, const char* font, const float text_height, const float thickness, bool is_bold, bool is_italic, TriangleMesh& text_mesh)
|
||||||
|
{
|
||||||
|
Handle(Font_FontMgr) aFontMgr = Font_FontMgr::GetInstance();
|
||||||
|
if (aFontMgr->GetAvailableFonts().IsEmpty())
|
||||||
|
aFontMgr->InitFontDataBase();
|
||||||
|
|
||||||
|
TopoDS_Shape aTextBase;
|
||||||
|
Font_FontAspect aFontAspect = Font_FontAspect_UNDEFINED;
|
||||||
|
if (is_bold && is_italic)
|
||||||
|
aFontAspect = Font_FontAspect_BoldItalic;
|
||||||
|
else if (is_bold)
|
||||||
|
aFontAspect = Font_FontAspect_Bold;
|
||||||
|
else if (is_italic)
|
||||||
|
aFontAspect = Font_FontAspect_Italic;
|
||||||
|
else
|
||||||
|
aFontAspect = Font_FontAspect_Regular;
|
||||||
|
|
||||||
|
if (!TextToBRep(text, font, text_height, aFontAspect, aTextBase))
|
||||||
|
return;
|
||||||
|
|
||||||
|
TopoDS_Shape aTextShape;
|
||||||
|
if (!Prism(aTextBase, thickness, aTextShape))
|
||||||
|
return;
|
||||||
|
|
||||||
|
MakeMesh(aTextShape, text_mesh);
|
||||||
|
}
|
||||||
|
|
||||||
|
}; // namespace Slic3r
|
|
@ -0,0 +1,12 @@
|
||||||
|
#ifndef slic3r_Text_Shape_hpp_
|
||||||
|
#define slic3r_Text_Shape_hpp_
|
||||||
|
|
||||||
|
namespace Slic3r {
|
||||||
|
class TriangleMesh;
|
||||||
|
|
||||||
|
extern std::vector<std::string> init_occt_fonts();
|
||||||
|
extern void load_text_shape(const char* text, const char* font, const float text_height, const float thickness, bool is_bold, bool is_italic, TriangleMesh& text_mesh);
|
||||||
|
|
||||||
|
}; // namespace Slic3r
|
||||||
|
|
||||||
|
#endif // slic3r_Text_Shape_hpp_
|
|
@ -129,6 +129,8 @@ set(SLIC3R_GUI_SOURCES
|
||||||
GUI/Gizmos/GLGizmoFaceDetector.hpp
|
GUI/Gizmos/GLGizmoFaceDetector.hpp
|
||||||
GUI/Gizmos/GLGizmoSeam.cpp
|
GUI/Gizmos/GLGizmoSeam.cpp
|
||||||
GUI/Gizmos/GLGizmoSeam.hpp
|
GUI/Gizmos/GLGizmoSeam.hpp
|
||||||
|
GUI/Gizmos/GLGizmoText.cpp
|
||||||
|
GUI/Gizmos/GLGizmoText.hpp
|
||||||
GUI/GLSelectionRectangle.cpp
|
GUI/GLSelectionRectangle.cpp
|
||||||
GUI/GLSelectionRectangle.hpp
|
GUI/GLSelectionRectangle.hpp
|
||||||
GUI/Gizmos/GizmoObjectManipulation.cpp
|
GUI/Gizmos/GizmoObjectManipulation.cpp
|
||||||
|
|
|
@ -2069,6 +2069,45 @@ void ObjectList::load_mesh_object(const TriangleMesh &mesh, const wxString &name
|
||||||
#endif /* _DEBUG */
|
#endif /* _DEBUG */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ObjectList::load_mesh_part(const TriangleMesh& mesh, const wxString& name, bool center)
|
||||||
|
{
|
||||||
|
wxDataViewItem item = GetSelection();
|
||||||
|
// we can add volumes for Object or Instance
|
||||||
|
if (!item || !(m_objects_model->GetItemType(item) & (itObject | itInstance)))
|
||||||
|
return;
|
||||||
|
const int obj_idx = m_objects_model->GetObjectIdByItem(item);
|
||||||
|
|
||||||
|
if (obj_idx < 0) return;
|
||||||
|
|
||||||
|
// Get object item, if Instance is selected
|
||||||
|
if (m_objects_model->GetItemType(item) & itInstance)
|
||||||
|
item = m_objects_model->GetItemById(obj_idx);
|
||||||
|
|
||||||
|
take_snapshot("Load Mesh Part");
|
||||||
|
|
||||||
|
ModelObject* mo = (*m_objects)[obj_idx];
|
||||||
|
ModelVolume* mv = mo->add_volume(mesh);
|
||||||
|
mv->name = name.ToStdString();
|
||||||
|
|
||||||
|
std::vector<ModelVolume*> volumes;
|
||||||
|
volumes.push_back(mv);
|
||||||
|
wxDataViewItemArray items = reorder_volumes_and_get_selection(obj_idx, [volumes](const ModelVolume* volume) {
|
||||||
|
return std::find(volumes.begin(), volumes.end(), volume) != volumes.end(); });
|
||||||
|
|
||||||
|
wxGetApp().plater()->canvas3D()->update_instance_printable_state_for_object((size_t)obj_idx);
|
||||||
|
|
||||||
|
if (items.size() > 1) {
|
||||||
|
m_selection_mode = smVolume;
|
||||||
|
m_last_selected_item = wxDataViewItem(nullptr);
|
||||||
|
}
|
||||||
|
select_items(items);
|
||||||
|
|
||||||
|
selection_changed();
|
||||||
|
|
||||||
|
//BBS: notify partplate the modify
|
||||||
|
notify_instance_updated(obj_idx);
|
||||||
|
}
|
||||||
|
|
||||||
//BBS
|
//BBS
|
||||||
void ObjectList::del_object(const int obj_idx, bool refresh_immediately)
|
void ObjectList::del_object(const int obj_idx, bool refresh_immediately)
|
||||||
{
|
{
|
||||||
|
|
|
@ -281,6 +281,8 @@ public:
|
||||||
void load_generic_subobject(const std::string& type_name, const ModelVolumeType type);
|
void load_generic_subobject(const std::string& type_name, const ModelVolumeType type);
|
||||||
void load_shape_object(const std::string &type_name);
|
void load_shape_object(const std::string &type_name);
|
||||||
void load_mesh_object(const TriangleMesh &mesh, const wxString &name, bool center = true);
|
void load_mesh_object(const TriangleMesh &mesh, const wxString &name, bool center = true);
|
||||||
|
// BBS
|
||||||
|
void load_mesh_part(const TriangleMesh& mesh, const wxString& name, bool center = true);
|
||||||
void del_object(const int obj_idx, bool refresh_immediately = true);
|
void del_object(const int obj_idx, bool refresh_immediately = true);
|
||||||
void del_subobject_item(wxDataViewItem& item);
|
void del_subobject_item(wxDataViewItem& item);
|
||||||
void del_settings_from_config(const wxDataViewItem& parent_item);
|
void del_settings_from_config(const wxDataViewItem& parent_item);
|
||||||
|
|
|
@ -0,0 +1,137 @@
|
||||||
|
// Include GLGizmoBase.hpp before I18N.hpp as it includes some libigl code, which overrides our localization "L" macro.
|
||||||
|
#include "GLGizmoText.hpp"
|
||||||
|
#include "slic3r/GUI/GLCanvas3D.hpp"
|
||||||
|
#include "slic3r/GUI/Gizmos/GLGizmosCommon.hpp"
|
||||||
|
#include "slic3r/GUI/GUI_App.hpp"
|
||||||
|
#include "slic3r/GUI/ImGuiWrapper.hpp"
|
||||||
|
#include "slic3r/GUI/GUI_ObjectList.hpp"
|
||||||
|
|
||||||
|
#include "libslic3r/Geometry/ConvexHull.hpp"
|
||||||
|
#include "libslic3r/Model.hpp"
|
||||||
|
|
||||||
|
#include "libslic3r/Shape/TextShape.hpp"
|
||||||
|
|
||||||
|
#include <numeric>
|
||||||
|
|
||||||
|
#include <GL/glew.h>
|
||||||
|
|
||||||
|
namespace Slic3r {
|
||||||
|
namespace GUI {
|
||||||
|
|
||||||
|
static double g_normal_precise = 0.0015;
|
||||||
|
|
||||||
|
GLGizmoText::GLGizmoText(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id)
|
||||||
|
: GLGizmoBase(parent, icon_filename, sprite_id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GLGizmoText::on_init()
|
||||||
|
{
|
||||||
|
m_avail_font_names = init_occt_fonts();
|
||||||
|
m_shortcut_key = WXK_CONTROL_T;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLGizmoText::on_set_state()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CommonGizmosDataID GLGizmoText::on_get_requirements() const
|
||||||
|
{
|
||||||
|
return CommonGizmosDataID::SelectionInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string GLGizmoText::on_get_name() const
|
||||||
|
{
|
||||||
|
return _u8L("Text shape");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GLGizmoText::on_is_activable() const
|
||||||
|
{
|
||||||
|
// This is assumed in GLCanvas3D::do_rotate, do not change this
|
||||||
|
// without updating that function too.
|
||||||
|
return m_parent.get_selection().is_single_full_instance();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLGizmoText::on_render()
|
||||||
|
{
|
||||||
|
// TODO:
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLGizmoText::on_render_for_picking()
|
||||||
|
{
|
||||||
|
// TODO:
|
||||||
|
}
|
||||||
|
|
||||||
|
// BBS
|
||||||
|
void GLGizmoText::on_render_input_window(float x, float y, float bottom_limit)
|
||||||
|
{
|
||||||
|
static float last_y = 0.0f;
|
||||||
|
static float last_h = 0.0f;
|
||||||
|
|
||||||
|
float space_size = m_imgui->get_style_scaling() * 8;
|
||||||
|
float font_cap = m_imgui->calc_text_size("Font ").x;
|
||||||
|
float size_cap = m_imgui->calc_text_size("Size ").x;
|
||||||
|
float thickness_cap = m_imgui->calc_text_size("Thickness ").x;
|
||||||
|
float caption_size = std::max(std::max(font_cap, size_cap), thickness_cap) + 2 * space_size;
|
||||||
|
|
||||||
|
m_imgui->begin(_L("Text"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse);
|
||||||
|
|
||||||
|
// adjust window position to avoid overlap the view toolbar
|
||||||
|
const float win_h = ImGui::GetWindowHeight();
|
||||||
|
y = std::min(y, bottom_limit - win_h);
|
||||||
|
ImGui::SetWindowPos(ImVec2(x, y), ImGuiCond_Always);
|
||||||
|
if (last_h != win_h || last_y != y) {
|
||||||
|
// ask canvas for another frame to render the window in the correct position
|
||||||
|
m_imgui->set_requires_extra_frame();
|
||||||
|
if (last_h != win_h)
|
||||||
|
last_h = win_h;
|
||||||
|
if (last_y != y)
|
||||||
|
last_y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::AlignTextToFramePadding();
|
||||||
|
|
||||||
|
const char** cstr_font_names = (const char**)calloc(m_avail_font_names.size(), sizeof(const char*));
|
||||||
|
for (int i = 0; i < m_avail_font_names.size(); i++)
|
||||||
|
cstr_font_names[i] = m_avail_font_names[i].c_str();
|
||||||
|
|
||||||
|
ImGui::InputText("", m_text, sizeof(m_text));
|
||||||
|
|
||||||
|
ImGui::PushItemWidth(caption_size);
|
||||||
|
ImGui::Text("Font ");
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::PushItemWidth(150);
|
||||||
|
ImGui::Combo("##Font", &m_curr_font_idx, cstr_font_names, m_avail_font_names.size());
|
||||||
|
|
||||||
|
ImGui::PushItemWidth(caption_size);
|
||||||
|
ImGui::Text("Size ");
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::PushItemWidth(150);
|
||||||
|
ImGui::InputFloat("###font_size", &m_font_size);
|
||||||
|
|
||||||
|
ImGui::PushItemWidth(caption_size);
|
||||||
|
ImGui::Text("Thickness ");
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::PushItemWidth(150);
|
||||||
|
ImGui::InputFloat("###text_thickness", &m_thickness);
|
||||||
|
|
||||||
|
ImGui::Checkbox("Bold", &m_bold);
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::Checkbox("Italic", &m_italic);
|
||||||
|
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
|
bool add_clicked = m_imgui->button(_L("Add"));
|
||||||
|
if (add_clicked) {
|
||||||
|
TriangleMesh mesh;
|
||||||
|
load_text_shape(m_text, m_font_name.c_str(), m_font_size, m_thickness, m_bold, m_italic, mesh);
|
||||||
|
ObjectList* obj_list = wxGetApp().obj_list();
|
||||||
|
obj_list->load_mesh_part(mesh, "text_shape");
|
||||||
|
}
|
||||||
|
|
||||||
|
m_imgui->end();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace GUI
|
||||||
|
} // namespace Slic3r
|
|
@ -0,0 +1,43 @@
|
||||||
|
#ifndef slic3r_GLGizmoText_hpp_
|
||||||
|
#define slic3r_GLGizmoText_hpp_
|
||||||
|
|
||||||
|
#include "GLGizmoBase.hpp"
|
||||||
|
#include "slic3r/GUI/3DScene.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
namespace Slic3r {
|
||||||
|
|
||||||
|
enum class ModelVolumeType : int;
|
||||||
|
|
||||||
|
namespace GUI {
|
||||||
|
|
||||||
|
class GLGizmoText : public GLGizmoBase
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::vector<std::string> m_avail_font_names;
|
||||||
|
char m_text[256] = { 0 };
|
||||||
|
std::string m_font_name;
|
||||||
|
float m_font_size = 16.f;
|
||||||
|
int m_curr_font_idx = 0;
|
||||||
|
bool m_bold = true;
|
||||||
|
bool m_italic = false;
|
||||||
|
float m_thickness = 2.f;
|
||||||
|
|
||||||
|
public:
|
||||||
|
GLGizmoText(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual bool on_init() override;
|
||||||
|
virtual std::string on_get_name() const override;
|
||||||
|
virtual bool on_is_activable() const override;
|
||||||
|
virtual void on_render() override;
|
||||||
|
virtual void on_render_for_picking() override;
|
||||||
|
virtual void on_set_state() override;
|
||||||
|
virtual CommonGizmosDataID on_get_requirements() const override;
|
||||||
|
virtual void on_render_input_window(float x, float y, float bottom_limit);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace GUI
|
||||||
|
} // namespace Slic3r
|
||||||
|
|
||||||
|
#endif // slic3r_GLGizmoText_hpp_
|
|
@ -22,6 +22,7 @@
|
||||||
#include "slic3r/GUI/Gizmos/GLGizmoSeam.hpp"
|
#include "slic3r/GUI/Gizmos/GLGizmoSeam.hpp"
|
||||||
#include "slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.hpp"
|
#include "slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.hpp"
|
||||||
#include "slic3r/GUI/Gizmos/GLGizmoSimplify.hpp"
|
#include "slic3r/GUI/Gizmos/GLGizmoSimplify.hpp"
|
||||||
|
#include "slic3r/GUI/Gizmos/GLGizmoText.hpp"
|
||||||
|
|
||||||
#include "libslic3r/format.hpp"
|
#include "libslic3r/format.hpp"
|
||||||
#include "libslic3r/Model.hpp"
|
#include "libslic3r/Model.hpp"
|
||||||
|
@ -146,6 +147,7 @@ bool GLGizmosManager::init()
|
||||||
m_gizmos.emplace_back(new GLGizmoAdvancedCut(m_parent, "toolbar_cut.svg", EType::Cut));
|
m_gizmos.emplace_back(new GLGizmoAdvancedCut(m_parent, "toolbar_cut.svg", EType::Cut));
|
||||||
m_gizmos.emplace_back(new GLGizmoFdmSupports(m_parent, "toolbar_support.svg", EType::FdmSupports));
|
m_gizmos.emplace_back(new GLGizmoFdmSupports(m_parent, "toolbar_support.svg", EType::FdmSupports));
|
||||||
m_gizmos.emplace_back(new GLGizmoSeam(m_parent, "toolbar_seam.svg", EType::Seam));
|
m_gizmos.emplace_back(new GLGizmoSeam(m_parent, "toolbar_seam.svg", EType::Seam));
|
||||||
|
m_gizmos.emplace_back(new GLGizmoText(m_parent, "toolbar_text.svg", EType::Text));
|
||||||
m_gizmos.emplace_back(new GLGizmoMmuSegmentation(m_parent, "mmu_segmentation.svg", EType::MmuSegmentation));
|
m_gizmos.emplace_back(new GLGizmoMmuSegmentation(m_parent, "mmu_segmentation.svg", EType::MmuSegmentation));
|
||||||
m_gizmos.emplace_back(new GLGizmoSimplify(m_parent, "reduce_triangles.svg", EType::Simplify));
|
m_gizmos.emplace_back(new GLGizmoSimplify(m_parent, "reduce_triangles.svg", EType::Simplify));
|
||||||
//m_gizmos.emplace_back(new GLGizmoSlaSupports(m_parent, "sla_supports.svg", sprite_id++));
|
//m_gizmos.emplace_back(new GLGizmoSlaSupports(m_parent, "sla_supports.svg", sprite_id++));
|
||||||
|
|
|
@ -72,6 +72,8 @@ public:
|
||||||
Cut,
|
Cut,
|
||||||
FdmSupports,
|
FdmSupports,
|
||||||
Seam,
|
Seam,
|
||||||
|
// BBS
|
||||||
|
Text,
|
||||||
MmuSegmentation,
|
MmuSegmentation,
|
||||||
Simplify,
|
Simplify,
|
||||||
SlaSupports,
|
SlaSupports,
|
||||||
|
|
Loading…
Reference in New Issue