discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

Configuration selection

DC
Dan Christian
Thu, Sep 13, 2018 7:16 PM

I want to select between multiple different configurations and want to
understand how to do that in a functional language.

In an imperative language I would do:
model = 'A';
if (model == 'A') {
dim_a = 1;
dim_b = 2;
}  else if (model == 'B') {
dim_a = 3;
dim_b = 4;
} else {  // default configuration
dim_a = 5;
dim_b = 6;
}

I may have many configurations and variables for each one.  This simple
example could be done with ? :, but that gets super messy as things get
more complex.

What's the best way to do this in OpenScad?

Dan

I want to select between multiple different configurations and want to understand how to do that in a functional language. In an imperative language I would do: model = 'A'; if (model == 'A') { dim_a = 1; dim_b = 2; } else if (model == 'B') { dim_a = 3; dim_b = 4; } else { // default configuration dim_a = 5; dim_b = 6; } I may have many configurations and variables for each one. This simple example could be done with ? :, but that gets super messy as things get more complex. What's the best way to do this in OpenScad? Dan
MF
Michael Frey
Thu, Sep 13, 2018 8:20 PM

Hi Dan,

I see two practical approaches:

Approach 1:
If you don´t mind Development snapshoots, try our customizer.
You can get those snapshoots from http://www.openscad.org/downloads.html
You also have to go into the preferences and enable the customzier.

In the customizer you can handle your configurations as so called presets.

https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/WIP#Customizer

Approach 2:
If you want to stay on the release line of openscad:
I would write a "base_model.scad" (or something like that), which is let
us say model default:
    dim_a = 5;
    dim_b = 6;
    //lots of code that creates the actual model

For model b, I would create a file called "model_b.scad" and then simply
    include <base_model.scad>;
    dim_a = 1;
    dim_b = 2;

For model b, I would create a file called "model_b.scad" and then simply
    include <base_model.scad>;
    dim_a = 3;
    dim_b = 4;

The trick is, that the last assignment overwrites any previous
assignments to a variable.

Every model has then its own file.
Most of the code being in base_model.scad.
The other files only need to overwrite the variables.

Depending on what you really want/need, use might also be an option.
But when you use "use", you need a bit more code for each configuration.

see also
https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Include_Statement

With Kind regards,
Michael Frey

Hi Dan, I see two practical approaches: *Approach 1:* If you don´t mind Development snapshoots, try our customizer. You can get those snapshoots from http://www.openscad.org/downloads.html You also have to go into the preferences and enable the customzier. In the customizer you can handle your configurations as so called presets. https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/WIP#Customizer *Approach 2:* If you want to stay on the release line of openscad: I would write a "base_model.scad" (or something like that), which is let us say model default:     dim_a = 5;     dim_b = 6;     //lots of code that creates the actual model For model b, I would create a file called "model_b.scad" and then simply     include <base_model.scad>;     dim_a = 1;     dim_b = 2; For model b, I would create a file called "model_b.scad" and then simply     include <base_model.scad>;     dim_a = 3;     dim_b = 4; The trick is, that the last assignment overwrites any previous assignments to a variable. Every model has then its own file. Most of the code being in base_model.scad. The other files only need to overwrite the variables. Depending on what you really want/need, use might also be an option. But when you use "use", you need a bit more code for each configuration. see also https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Include_Statement With Kind regards, Michael Frey
DC
Dan Christian
Thu, Sep 13, 2018 11:16 PM

Thanks!

Approach 2 should work for me.

Dan

On Thu, Sep 13, 2018 at 1:21 PM Michael Frey michael.frey@gmx.ch wrote:

Hi Dan,

I see two practical approaches:

Approach 1:
If you don´t mind Development snapshoots, try our customizer.
You can get those snapshoots from http://www.openscad.org/downloads.html
You also have to go into the preferences and enable the customzier.

In the customizer you can handle your configurations as so called presets.

https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/WIP#Customizer

Approach 2:
If you want to stay on the release line of openscad:
I would write a "base_model.scad" (or something like that), which is let
us say model default:
dim_a = 5;
dim_b = 6;
//lots of code that creates the actual model

For model b, I would create a file called "model_b.scad" and then simply
include <base_model.scad>;
dim_a = 1;
dim_b = 2;

For model b, I would create a file called "model_b.scad" and then simply
include <base_model.scad>;
dim_a = 3;
dim_b = 4;

The trick is, that the last assignment overwrites any previous assignments
to a variable.

Every model has then its own file.
Most of the code being in base_model.scad.
The other files only need to overwrite the variables.

Depending on what you really want/need, use might also be an option.
But when you use "use", you need a bit more code for each configuration.

see also
https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Include_Statement

With Kind regards,
Michael Frey


OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

Thanks! Approach 2 should work for me. Dan On Thu, Sep 13, 2018 at 1:21 PM Michael Frey <michael.frey@gmx.ch> wrote: > Hi Dan, > > I see two practical approaches: > > *Approach 1:* > If you don´t mind Development snapshoots, try our customizer. > You can get those snapshoots from http://www.openscad.org/downloads.html > You also have to go into the preferences and enable the customzier. > > In the customizer you can handle your configurations as so called presets. > > https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/WIP#Customizer > > *Approach 2:* > If you want to stay on the release line of openscad: > I would write a "base_model.scad" (or something like that), which is let > us say model default: > dim_a = 5; > dim_b = 6; > //lots of code that creates the actual model > > For model b, I would create a file called "model_b.scad" and then simply > include <base_model.scad>; > dim_a = 1; > dim_b = 2; > > For model b, I would create a file called "model_b.scad" and then simply > include <base_model.scad>; > dim_a = 3; > dim_b = 4; > > The trick is, that the last assignment overwrites any previous assignments > to a variable. > > Every model has then its own file. > Most of the code being in base_model.scad. > The other files only need to overwrite the variables. > > Depending on what you really want/need, use might also be an option. > But when you use "use", you need a bit more code for each configuration. > > see also > https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Include_Statement > > With Kind regards, > Michael Frey > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >
T
TLC123
Fri, Sep 14, 2018 8:09 AM

Assign values to dim_a and dim_b separately.
Use the  Ternary conditional operator - ?:
usage:
/condition expression/ ? /expression if true /: /expression if false/ ;

In this case one ternary operation is nested inside one other.

model = 'A';

  dim_a = (model == 'A') ? 1:(model == 'B')?3:5;
  dim_b = (model == 'A') ? 2:(model == 'B')?4:6;

// "let" dim_a= "if"(model == 'A')? "then" 1 : "else if"(model == 'B')?
"then" 3: "else" 5

--
Sent from: http://forum.openscad.org/

Assign values to dim_a and dim_b separately. Use the Ternary conditional operator - ?: usage: /condition expression/ ? /expression if true /: /expression if false/ ; In this case one ternary operation is nested inside one other. model = 'A'; dim_a = (model == 'A') ? 1:(model == 'B')?3:5; dim_b = (model == 'A') ? 2:(model == 'B')?4:6; // "let" dim_a= "if"(model == 'A')? "then" 1 : "else if"(model == 'B')? "then" 3: "else" 5 -- Sent from: http://forum.openscad.org/
R
Ronaldo
Fri, Sep 14, 2018 3:44 PM

​If you have many parameters for each alternative model, it is a good idea to
collect them in a list for each model.

modelA = [ ​1, // dim_a
2, // dim_b
[1,2]  // vec_a // some vector parameter
...
];
modelB = [ ​3, // dim_a
4, // dim_b
[2,3]  // vec_a
...
];
modelC = [ ​5, // dim_a
6, // dim_b
[3,4]  // vec_a
...
];

Then, select the parameter set with just one :? operator

modelset = model=='A' ? modelA : model=='B' ? modelB : modelC;

and retrieve the parameters from modelset:

dim_a = modelset[0];
dim_b = modelset[1];
vec_a = modelset[2];

With a few changes, you will be able to add more parameters without touching
the selection operation.

If the selection key 'model' is an integer instead of a char, you can even
avoid the :? operator at all.

modellist = [modelA, modelB, modelC];
...
modelset = modellist[model];

--
Sent from: http://forum.openscad.org/

​If you have many parameters for each alternative model, it is a good idea to collect them in a list for each model. modelA = [ ​1, // dim_a 2, // dim_b [1,2] // vec_a // some vector parameter ... ]; modelB = [ ​3, // dim_a 4, // dim_b [2,3] // vec_a ... ]; modelC = [ ​5, // dim_a 6, // dim_b [3,4] // vec_a ... ]; Then, select the parameter set with just one :? operator modelset = model=='A' ? modelA : model=='B' ? modelB : modelC; and retrieve the parameters from modelset: dim_a = modelset[0]; dim_b = modelset[1]; vec_a = modelset[2]; With a few changes, you will be able to add more parameters without touching the selection operation. If the selection key 'model' is an integer instead of a char, you can even avoid the :? operator at all. modellist = [modelA, modelB, modelC]; ... modelset = modellist[model]; -- Sent from: http://forum.openscad.org/
R
runsun
Fri, Sep 14, 2018 8:45 PM

The  associative array
https://github.com/runsun/OpenSCAD_Tips/blob/master/snippets.md#hash *
might be an option:

models = [ "A", [  dim_a,1, dim_b, 2 ]
, "B", [  dim_a,3, dim_b, 4 ]
, ...
];

data = hash( models, "A");
dim_a = hash( data, "dim_a");
dim_b = hash( data, "dim_b");


$  Runsun Pan, PhD $ libs: scadx , doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), editor of choice: CudaText  ( OpenSCAD lexer ); $ Tips ; $ Snippets

--
Sent from: http://forum.openscad.org/

The associative array <https://github.com/runsun/OpenSCAD_Tips/blob/master/snippets.md#hash> * might be an option: models = [ "A", [ dim_a,1, dim_b, 2 ] , "B", [ dim_a,3, dim_b, 4 ] , ... ]; data = hash( models, "A"); dim_a = hash( data, "dim_a"); dim_b = hash( data, "dim_b"); ----- $ Runsun Pan, PhD $ libs: scadx , doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), editor of choice: CudaText ( OpenSCAD lexer );&nbsp;$ Tips ;&nbsp;$ Snippets -- Sent from: http://forum.openscad.org/
JB
Jordan Brown
Fri, Sep 14, 2018 10:01 PM

On 9/14/2018 8:44 AM, Ronaldo wrote:

​If you have many parameters for each alternative model, it is a good idea to
collect them in a list for each model.

modelA = [ ​1, // dim_a
2, // dim_b
[1,2]  // vec_a // some vector parameter
...
];
modelB = [ ​3, // dim_a
4, // dim_b
[2,3]  // vec_a
...
];
modelC = [ ​5, // dim_a
6, // dim_b
[3,4]  // vec_a
...
];

Then, select the parameter set with just one :? operator

modelset = model=='A' ? modelA : model=='B' ? modelB : modelC;

That was what I was thinking, with a couple of additional notes...

I would try to align the definitions of model[ABC] into a table-like form:

//         a  b  c
modelA = [ ​1, 2, [1,2], ... ];
modelB = [ ​3, 4, [2,3], ... ];
modelC = [ ​5, 6, [3,4], ... ];

and if the number of variants is non-trivial, then do something similar
with the ?: sequence:

modelset =
    model == 'A' ? modelA :
    model == 'B' ? modelB :
    modelC

... though better would be to have the final "else" generate an error,
so that a typo doesn't silently give you the default.  I don't happen to
remember any good ways to do that, and don't have the time right now to
look.

On 9/14/2018 8:44 AM, Ronaldo wrote: > ​If you have many parameters for each alternative model, it is a good idea to > collect them in a list for each model. > > modelA = [ ​1, // dim_a > 2, // dim_b > [1,2] // vec_a // some vector parameter > ... > ]; > modelB = [ ​3, // dim_a > 4, // dim_b > [2,3] // vec_a > ... > ]; > modelC = [ ​5, // dim_a > 6, // dim_b > [3,4] // vec_a > ... > ]; > > Then, select the parameter set with just one :? operator > > modelset = model=='A' ? modelA : model=='B' ? modelB : modelC; That was what I was thinking, with a couple of additional notes... I would try to align the definitions of model[ABC] into a table-like form: // a b c modelA = [ ​1, 2, [1,2], ... ]; modelB = [ ​3, 4, [2,3], ... ]; modelC = [ ​5, 6, [3,4], ... ]; and if the number of variants is non-trivial, then do something similar with the ?: sequence: modelset = model == 'A' ? modelA : model == 'B' ? modelB : modelC ... though better would be to have the final "else" generate an error, so that a typo doesn't silently give you the default.  I don't happen to remember any good ways to do that, and don't have the time right now to look.