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
|
||||
---
|
||||
|
||||
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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
@ -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
|
||||
// breaks MinGW for some obscure reason.
|
||||
static std::vector<Test::Case> *testCasesPtr;
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue