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
EvilSpirit 2016-05-03 13:44:10 +06:00 committed by whitequark
parent 5462fc6b3c
commit 6658b1fa2b
10 changed files with 2142 additions and 10 deletions

View File

@ -4,6 +4,10 @@ Changelog
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:
* Three.js: allow configuring projection for exported model, and initially
use the current viewport projection.

View File

@ -103,7 +103,7 @@ void SMesh::RemapFaces(Group *g, int remap) {
}
template<class T>
void Group::GenerateForStepAndRepeat(T *steps, T *outs) {
void Group::GenerateForStepAndRepeat(T *steps, T *outs, Group::CombineAs forWhat) {
T workA, workB;
workA = {};
workB = {};
@ -141,6 +141,8 @@ void Group::GenerateForStepAndRepeat(T *steps, T *outs) {
// And tack this transformed copy on to the return.
if(soFar->IsEmpty()) {
scratch->MakeFromCopyOf(&transd);
} else if (forWhat == CombineAs::ASSEMBLE) {
scratch->MakeFromAssemblyOf(soFar, &transd);
} else {
scratch->MakeFromUnionOf(soFar, &transd);
}
@ -202,8 +204,8 @@ void Group::GenerateShellAndMesh() {
srcg = SK.GetGroup(opA);
if(!srcg->suppress) {
GenerateForStepAndRepeat<SShell>(&(srcg->thisShell), &thisShell);
GenerateForStepAndRepeat<SMesh> (&(srcg->thisMesh), &thisMesh);
GenerateForStepAndRepeat<SShell>(&(srcg->thisShell), &thisShell, srcg->meshCombine);
GenerateForStepAndRepeat<SMesh> (&(srcg->thisMesh), &thisMesh, srcg->meshCombine);
}
} else if(type == Type::EXTRUDE && haveSrc) {
Group *src = SK.GetGroup(opA);

View File

@ -268,7 +268,7 @@ public:
bool IsMeshGroup();
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);
void GenerateDisplayItems();

View File

@ -352,12 +352,11 @@ void TextWindow::ShowGroupInfo() {
bool un = (g->meshCombine == Group::CombineAs::UNION);
bool diff = (g->meshCombine == Group::CombineAs::DIFFERENCE);
bool asy = (g->meshCombine == Group::CombineAs::ASSEMBLE);
bool asa = (g->type == Group::Type::LINKED);
Printf(false, " %Ftsolid model as");
Printf(false, "%Ba %f%D%Lc%Fd%s union%E "
"%f%D%Lc%Fd%s difference%E "
"%f%D%Lc%Fd%s%s%E ",
"%f%D%Lc%Fd%s assemble%E ",
&TextWindow::ScreenChangeGroupOption,
Group::CombineAs::UNION,
un ? RADIO_TRUE : RADIO_FALSE,
@ -366,8 +365,7 @@ void TextWindow::ShowGroupInfo() {
diff ? RADIO_TRUE : RADIO_FALSE,
&TextWindow::ScreenChangeGroupOption,
Group::CombineAs::ASSEMBLE,
asa ? (asy ? RADIO_TRUE : RADIO_FALSE) : " ",
asa ? " assemble" : "");
(asy ? RADIO_TRUE : RADIO_FALSE));
if(g->type == Group::Type::EXTRUDE ||
g->type == Group::Type::LATHE)

View File

@ -52,7 +52,9 @@ set(testsuite_SOURCES
request/cubic_periodic/test.cpp
request/datum_point/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
${testsuite_SOURCES})

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

File diff suppressed because it is too large Load Diff

View File

@ -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);
}

View File

@ -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
// breaks MinGW for some obscure reason.
static std::vector<Test::Case> *testCasesPtr;

View File

@ -25,6 +25,8 @@ public:
bool CheckLoad(const char *file, int line, const char *fixture);
bool CheckSave(const char *file, int line, const char *reference);
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 {
@ -54,4 +56,6 @@ using namespace SolveSpace;
#define CHECK_SAVE(fixture) \
do { if(!helper->CheckSave(__FILE__, __LINE__, fixture)) return; } while(0)
#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)