Allow combining extrude, lathe, translate and rotate group as assemblies.
This significantly improves performance e.g. in case of a sketch containing a multitude of wooden panels, as the meshes can be merely transformed instead of being joined.pull/97/head
parent
5462fc6b3c
commit
6658b1fa2b
|
@ -4,6 +4,10 @@ Changelog
|
||||||
3.0
|
3.0
|
||||||
---
|
---
|
||||||
|
|
||||||
|
New sketch features:
|
||||||
|
* Extrude, lathe, translate and rotate groups can now use the "assembly"
|
||||||
|
boolean operation, to increase performance.
|
||||||
|
|
||||||
New export/import features:
|
New export/import features:
|
||||||
* Three.js: allow configuring projection for exported model, and initially
|
* Three.js: allow configuring projection for exported model, and initially
|
||||||
use the current viewport projection.
|
use the current viewport projection.
|
||||||
|
|
|
@ -103,7 +103,7 @@ void SMesh::RemapFaces(Group *g, int remap) {
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
void Group::GenerateForStepAndRepeat(T *steps, T *outs) {
|
void Group::GenerateForStepAndRepeat(T *steps, T *outs, Group::CombineAs forWhat) {
|
||||||
T workA, workB;
|
T workA, workB;
|
||||||
workA = {};
|
workA = {};
|
||||||
workB = {};
|
workB = {};
|
||||||
|
@ -141,6 +141,8 @@ void Group::GenerateForStepAndRepeat(T *steps, T *outs) {
|
||||||
// And tack this transformed copy on to the return.
|
// And tack this transformed copy on to the return.
|
||||||
if(soFar->IsEmpty()) {
|
if(soFar->IsEmpty()) {
|
||||||
scratch->MakeFromCopyOf(&transd);
|
scratch->MakeFromCopyOf(&transd);
|
||||||
|
} else if (forWhat == CombineAs::ASSEMBLE) {
|
||||||
|
scratch->MakeFromAssemblyOf(soFar, &transd);
|
||||||
} else {
|
} else {
|
||||||
scratch->MakeFromUnionOf(soFar, &transd);
|
scratch->MakeFromUnionOf(soFar, &transd);
|
||||||
}
|
}
|
||||||
|
@ -202,8 +204,8 @@ void Group::GenerateShellAndMesh() {
|
||||||
srcg = SK.GetGroup(opA);
|
srcg = SK.GetGroup(opA);
|
||||||
|
|
||||||
if(!srcg->suppress) {
|
if(!srcg->suppress) {
|
||||||
GenerateForStepAndRepeat<SShell>(&(srcg->thisShell), &thisShell);
|
GenerateForStepAndRepeat<SShell>(&(srcg->thisShell), &thisShell, srcg->meshCombine);
|
||||||
GenerateForStepAndRepeat<SMesh> (&(srcg->thisMesh), &thisMesh);
|
GenerateForStepAndRepeat<SMesh> (&(srcg->thisMesh), &thisMesh, srcg->meshCombine);
|
||||||
}
|
}
|
||||||
} else if(type == Type::EXTRUDE && haveSrc) {
|
} else if(type == Type::EXTRUDE && haveSrc) {
|
||||||
Group *src = SK.GetGroup(opA);
|
Group *src = SK.GetGroup(opA);
|
||||||
|
|
|
@ -268,7 +268,7 @@ public:
|
||||||
bool IsMeshGroup();
|
bool IsMeshGroup();
|
||||||
|
|
||||||
void GenerateShellAndMesh();
|
void GenerateShellAndMesh();
|
||||||
template<class T> void GenerateForStepAndRepeat(T *steps, T *outs);
|
template<class T> void GenerateForStepAndRepeat(T *steps, T *outs, Group::CombineAs forWhat);
|
||||||
template<class T> void GenerateForBoolean(T *a, T *b, T *o, Group::CombineAs how);
|
template<class T> void GenerateForBoolean(T *a, T *b, T *o, Group::CombineAs how);
|
||||||
void GenerateDisplayItems();
|
void GenerateDisplayItems();
|
||||||
|
|
||||||
|
|
|
@ -352,12 +352,11 @@ void TextWindow::ShowGroupInfo() {
|
||||||
bool un = (g->meshCombine == Group::CombineAs::UNION);
|
bool un = (g->meshCombine == Group::CombineAs::UNION);
|
||||||
bool diff = (g->meshCombine == Group::CombineAs::DIFFERENCE);
|
bool diff = (g->meshCombine == Group::CombineAs::DIFFERENCE);
|
||||||
bool asy = (g->meshCombine == Group::CombineAs::ASSEMBLE);
|
bool asy = (g->meshCombine == Group::CombineAs::ASSEMBLE);
|
||||||
bool asa = (g->type == Group::Type::LINKED);
|
|
||||||
|
|
||||||
Printf(false, " %Ftsolid model as");
|
Printf(false, " %Ftsolid model as");
|
||||||
Printf(false, "%Ba %f%D%Lc%Fd%s union%E "
|
Printf(false, "%Ba %f%D%Lc%Fd%s union%E "
|
||||||
"%f%D%Lc%Fd%s difference%E "
|
"%f%D%Lc%Fd%s difference%E "
|
||||||
"%f%D%Lc%Fd%s%s%E ",
|
"%f%D%Lc%Fd%s assemble%E ",
|
||||||
&TextWindow::ScreenChangeGroupOption,
|
&TextWindow::ScreenChangeGroupOption,
|
||||||
Group::CombineAs::UNION,
|
Group::CombineAs::UNION,
|
||||||
un ? RADIO_TRUE : RADIO_FALSE,
|
un ? RADIO_TRUE : RADIO_FALSE,
|
||||||
|
@ -366,8 +365,7 @@ void TextWindow::ShowGroupInfo() {
|
||||||
diff ? RADIO_TRUE : RADIO_FALSE,
|
diff ? RADIO_TRUE : RADIO_FALSE,
|
||||||
&TextWindow::ScreenChangeGroupOption,
|
&TextWindow::ScreenChangeGroupOption,
|
||||||
Group::CombineAs::ASSEMBLE,
|
Group::CombineAs::ASSEMBLE,
|
||||||
asa ? (asy ? RADIO_TRUE : RADIO_FALSE) : " ",
|
(asy ? RADIO_TRUE : RADIO_FALSE));
|
||||||
asa ? " assemble" : "");
|
|
||||||
|
|
||||||
if(g->type == Group::Type::EXTRUDE ||
|
if(g->type == Group::Type::EXTRUDE ||
|
||||||
g->type == Group::Type::LATHE)
|
g->type == Group::Type::LATHE)
|
||||||
|
|
|
@ -52,7 +52,9 @@ set(testsuite_SOURCES
|
||||||
request/cubic_periodic/test.cpp
|
request/cubic_periodic/test.cpp
|
||||||
request/datum_point/test.cpp
|
request/datum_point/test.cpp
|
||||||
request/line_segment/test.cpp
|
request/line_segment/test.cpp
|
||||||
request/ttf_text/test.cpp)
|
request/ttf_text/test.cpp
|
||||||
|
group/translate_asy/test.cpp
|
||||||
|
)
|
||||||
|
|
||||||
add_executable(solvespace_testsuite
|
add_executable(solvespace_testsuite
|
||||||
${testsuite_SOURCES})
|
${testsuite_SOURCES})
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 8.1 KiB |
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,22 @@
|
||||||
|
#include "harness.h"
|
||||||
|
|
||||||
|
TEST_CASE(normal_roundtrip) {
|
||||||
|
CHECK_LOAD("normal.slvs");
|
||||||
|
CHECK_RENDER_ISO("normal.png");
|
||||||
|
CHECK_SAVE("normal.slvs");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE(normal_inters) {
|
||||||
|
CHECK_LOAD("normal.slvs");
|
||||||
|
|
||||||
|
Group *g = SK.GetGroup(SS.GW.activeGroup);
|
||||||
|
SMesh *m = &g->displayMesh;
|
||||||
|
|
||||||
|
SEdgeList el = {};
|
||||||
|
bool inters, leaks;
|
||||||
|
SKdNode::From(m)->MakeCertainEdgesInto(&el,
|
||||||
|
EdgeKind::SELF_INTER, /*coplanarIsInter=*/false, &inters, &leaks);
|
||||||
|
|
||||||
|
// The assembly is supposed to interfere.
|
||||||
|
CHECK_TRUE(inters);
|
||||||
|
}
|
|
@ -260,6 +260,18 @@ bool Test::Helper::CheckRender(const char *file, int line, const char *reference
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Test::Helper::CheckRenderXY(const char *file, int line, const char *fixture) {
|
||||||
|
SS.GW.projRight = Vector::From(1, 0, 0);
|
||||||
|
SS.GW.projUp = Vector::From(0, 1, 0);
|
||||||
|
return CheckRender(file, line, fixture);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Test::Helper::CheckRenderIso(const char *file, int line, const char *fixture) {
|
||||||
|
SS.GW.projRight = Vector::From(0.707, 0.000, -0.707);
|
||||||
|
SS.GW.projUp = Vector::From(-0.408, 0.816, -0.408);
|
||||||
|
return CheckRender(file, line, fixture);
|
||||||
|
}
|
||||||
|
|
||||||
// Avoid global constructors; using a global static vector instead of a local one
|
// Avoid global constructors; using a global static vector instead of a local one
|
||||||
// breaks MinGW for some obscure reason.
|
// breaks MinGW for some obscure reason.
|
||||||
static std::vector<Test::Case> *testCasesPtr;
|
static std::vector<Test::Case> *testCasesPtr;
|
||||||
|
|
|
@ -25,6 +25,8 @@ public:
|
||||||
bool CheckLoad(const char *file, int line, const char *fixture);
|
bool CheckLoad(const char *file, int line, const char *fixture);
|
||||||
bool CheckSave(const char *file, int line, const char *reference);
|
bool CheckSave(const char *file, int line, const char *reference);
|
||||||
bool CheckRender(const char *file, int line, const char *fixture);
|
bool CheckRender(const char *file, int line, const char *fixture);
|
||||||
|
bool CheckRenderXY(const char *file, int line, const char *fixture);
|
||||||
|
bool CheckRenderIso(const char *file, int line, const char *fixture);
|
||||||
};
|
};
|
||||||
|
|
||||||
class Case {
|
class Case {
|
||||||
|
@ -54,4 +56,6 @@ using namespace SolveSpace;
|
||||||
#define CHECK_SAVE(fixture) \
|
#define CHECK_SAVE(fixture) \
|
||||||
do { if(!helper->CheckSave(__FILE__, __LINE__, fixture)) return; } while(0)
|
do { if(!helper->CheckSave(__FILE__, __LINE__, fixture)) return; } while(0)
|
||||||
#define CHECK_RENDER(reference) \
|
#define CHECK_RENDER(reference) \
|
||||||
do { if(!helper->CheckRender(__FILE__, __LINE__, reference)) return; } while(0)
|
do { if(!helper->CheckRenderXY(__FILE__, __LINE__, reference)) return; } while(0)
|
||||||
|
#define CHECK_RENDER_ISO(reference) \
|
||||||
|
do { if(!helper->CheckRenderIso(__FILE__, __LINE__, reference)) return; } while(0)
|
||||||
|
|
Loading…
Reference in New Issue