// PoVRay 3.8 include File "objects.inc" // author: Bruno Cabasson // date: Jan 2022 // // Projet PROOF : // POV-Ray Object Oriented Features. Using dictionaries to describe objects and embryonic classes. // // Scene ojects. // // Things are described and manipulated within dictionaries, via an appropriate // set of macros. Among others, this allows information hiding, encapsulation, // manipulating instances of user-defined classes, with attributes and methods. // Method names are simply mangled with the class name in prefix, unless the method // can be named without. // // This include file defines classes descibing POV objects and // POV objects are then intantiated, or commited as we say here, through // a Xxx_commit() macro, where Xxx is the name of the class in question. // // All POV objects have a texture (= pigment, normal, finish) and a transform, and // may have a photon block. These are the standard attributes for all POV objects. // Slope provides macros to handle them. // // All POV object have specific attributes. // // Attributes values remain persistant throughout the parse process and this can be handy. // // When a class Xxx is finished described in its dictionnary, the POV object // is then 'commited' by the XXX_commit() macro, which uses the dictionary to // create the corresponding object. // // An example of the usage of dectionaries to handle user-defined classes is the // specific case of splines. See SLOPE's 'splines.inc'. // // PROOF does not define classes for global_settings {} block. // Native syntax is best. // // PROOF is ment to be used when appropriate ou handy. Object oriented features, even basic, // can be useful when it comes to organize a quite large amount of code and/or objects. // // An example showing the usefulness of this object-oriented layer is the animation // package found in SLOPE's 'animation.inc'. // //-------------------------------------------------------------------------- #ifndef (SLOPE_OBJECTS_INC) #declare SLOPE_OBJECTS_INC = version; #version 3.7; #include "colors.inc" #version 3.8; #include "oocore.inc" #include "collections.inc" // Private convenience macros #macro _commit_mangle(class) concat(class.classname, "_commit") #end #macro _spawn_mangle(class) concat(class.classname, "_spawn") #end // Public convenience macros #macro commit(this) #local code = concat(_commit_mangle(this.class), "(this)"); exec(code) #end #macro spawn(this) #local code = concat(_spawn_mangle(this.class), "(this)"); exec(code) #end #macro spawn_object(this, object_) #if (this._spawned) #error concat("\"", this.class.classname, " object already spawned." #end #local this._instance = object_; #local this._spawned = true; this._instance #end #macro set(this, property, value) #if (this._spawned) #error concat("\"", this.class.classname, "\" object already spawned. Cannot change properties.") #end #local property = value; #end // == class ObjectItem ============================ #declare ObjectItem = class ( "ObjectItem", no, None, // No parent , // No properties array {"commit"} // Not implemented => virtual. ) setvirtual(ObjectItem) // ================================================ // == class ObjectPhotons ========================= #declare ObjectPhotons = class ( "ObjectPhotons", yes, ObjectItem, // Parent class array { array mixed {"target_", TYPES._float_}, array mixed {"refraction_", TYPES._bool_}, array mixed {"reflection_", TYPES._bool_}, array mixed {"collect_", TYPES._bool_}, array mixed {"pass_through_", TYPES._bool_} }, , // No methods ) #macro new_ObjectPhotons(this, params_dict) #local this.target_ = check(params_dict.target_, TYPES._float_); #local this.refraction_ = check(params_dict.refraction_, TYPES._bool_); #local this.reflection_ = check(params_dict.reflection_, TYPES._bool_); #local this.collect_ = check(params_dict.collect_, TYPES._bool_); #local this.pass_through_ = check(params_dict.pass_through_, TYPES._bool_); #end #macro ObjectPhotons_dump(this, indent_level) #debug concat(indent[indent_level], "instance of \"", this.class.classname, "\"\n") #debug concat(indent[indent_level], "{\n") #debug concat(indent[indent_level + 1], "target ", tostring(this.target_, TYPES._float_), "\n") #debug concat(indent[indent_level + 1], "refraction ", onoff(this.refraction_) , "\n") #debug concat(indent[indent_level + 1], "reflection ", onoff(this.reflection_) , "\n") #debug concat(indent[indent_level + 1], "collect ", onoff(this.collect_) , "\n") #if (this.pass_through_) #debug concat(indent[indent_level + 1], "pass_through\n") #end #debug concat(indent[indent_level + 1], this.commit, "()\n") #debug concat(indent[indent_level], "}\n") #end #macro ObjectPhotons_commit(this) photons { target this.target_ refraction this.refraction_ reflection this.refraction_ collect this._collect #if (this.pass_through_) pass_through #end } #end // ================================================ // == class ObjectRadiosity ======================= #declare ObjectRadiosity = class ( "ObjectRadiosity", yes, ObjectItem, // Parent class array { array mixed {"importance_", TYPES._float_}, }, , ) #macro new_ObjectRadiosity(this, params_dict) #local this.importance_ = check(params_dict.importance_, TYPES._float_); #end #macro ObjectRadiosity_dump(this, indent_level) #debug concat(indent[indent_level], "instance of \"", this.class.classname, "\"\n") #debug concat(indent[indent_level], "{\n") #debug concat(indent[indent_level + 1], "importance ", tostring(this.importance_, TYPES._float_), "\n") #debug concat(indent[indent_level + 1], this.commit, "()\n") #debug concat(indent[indent_level], "}\n") #end #macro ObjectRadiosity_commit(this) radiosity {importance this.importance_} #end // ================================================ // == class ObjectModifiers ======================== #declare ObjectModifiers = class ( "ObjectModifiers", yes, ObjectItem, // Parent class array { array mixed {"texture_", TYPES._texture_}, array mixed {"_has_interior_texture", TYPES._bool_}, array mixed {"interior_texture_", TYPES._texture_}, array mixed {"_has_interior", TYPES._bool_}, array mixed {"interior_", TYPES._interior_}, array mixed {"_has_pigment", TYPES._bool_}, array mixed {"pigment_", TYPES._pigment_}, array mixed {"_has_normal", TYPES._bool_}, array mixed {"normal_", TYPES._normal_}, array mixed {"_has_finish", TYPES._bool_}, array mixed {"finish_", TYPES._finish_}, array mixed {"_has_transform", TYPES._bool_}, array mixed {"transform_", TYPES._transform_}, array mixed {"_has_object_photons", TYPES._bool_}, array mixed {"object_photons", TYPES._instance_, ObjectPhotons}, // No object photons identifier : cannot do #declare p = photons {...};, thus use a ObjectPhoton instance. array mixed {"_has_object_radiosity", TYPES._bool_}, array mixed {"object_radiosity", TYPES._instance_, ObjectRadiosity}, // No object radiosity identifier : cannot do #declare r = radiosity {...};, thus use a ObjectPhoton instance. array mixed {"_has_bounded_by", TYPES._bool_}, array mixed {"bounded_by_", TYPES._object_}, array mixed {"_has_clipped_by", TYPES._bool_}, array mixed {"clipped_by_", TYPES._object_}, array mixed {"double_illuminate_", TYPES._bool_}, array mixed {"hollow_", TYPES._bool_}, array mixed {"no_shadow_", TYPES._bool_}, array mixed {"no_image_", TYPES._bool_}, array mixed {"no_reflection_", TYPES._bool_}, array mixed {"no_radiosity_", TYPES._bool_}, }, , ) #macro new_ObjectModifiers(this, optional params_dict) #ifdef (local.params_dict) #ifdef (params_dict.texture_) #local this.texture_ = check(params_dict.texture_, TYPES._texture_); #else #local this.texture_ = DEFAULT_TEXTURE; #end #local this._has_pigment = no; #local this._has_normal = no; #local this._has_finish = no; #local this._has_interior_texture = no; #local this._has_interior = no; #local this._has_object_photons = no; #local this._has_object_radiosity = no; #local this._has_transform = no; #local this._has_bounded_by = no; #local this.double_illuminate_ = false; #local this.hollow_ = off; #local this.no_shadow_ = false; #local this.no_image_ = false; #local this.no_reflection_ = false; #local this.no_radiosity_ = false; #ifdef (params_dict.pigment_) #local this.pigment_ = check(params_dict.pigment_, TYPES._pigment_); #local this._has_pigment = yes; #end #ifdef (params_dict.normal_) #local this.normal_ = check(params_dict.normal_, TYPES._normal_); #local this._has_normal = yes; #end #ifdef (params_dict.finish_) #local this.finish_ = check(params_dict.finish_, TYPES._finish_); #local this._has_finish = yes; #end #ifdef (params_dict.interior_texture_) #local this.interior_texture_ = check(params_dict.interior_texture_, TYPES._texture_); #local this._has_interior_texture = yes; #end #ifdef (params_dict.interior_) #local this.interior_ = check(params_dict.interior_, TYPES._interior_); #local this._has_interior = yes; #end // No object photons identifier in POV-Sdl : cannot #declare p = photons {...};, // thus use a ObjectPhoton instance. #ifdef (params_dict.object_photons) #local p = check(params_dict.object_photons, TYPES._instance_); #if (instanceof(p, ObjectPhotons) #local this.object_photons = p; #else #error concat("ObjectModifiers : expected a ObjectPhotons instance, got ", p.class.classname, ".") #end #local this._has_object_photons = yes; #end // No object radiosity identifier in POV-Sdl : cannot #declare r = radiosity {...};, // thus use a ObjectRadiosity instance. #ifdef (params_dict.object_radiosity) #local or = check(params_dict.object_radiosity, TYPES._instance_); #if (instanceof(or, ObjectRadiosity) #local this.object_radiosity = or; #else #error concat("ObjectModifiers : expected a ObjectRadiosity instance, got ", or.class.classname, ".") #end #local this._has_object_radiosity = yes; #end #ifdef (params_dict.transform_) #local this.transform_ = check(params_dict.transform_, TYPES._transform_); #local this._has_transform = yes; #end #ifdef (params_dict.bounded_by_) #local this.bounded_by_ = check(params_dict.bounded_by_, TYPES._object_); #local this._has_bounded_by = yes; #end #ifdef (params_dict.clipped_by_) #local this.clipped_by_ = check(params_dict.clipped_by_, TYPES._object_); #local this._has_clipped_by = yes; #end #ifdef (params_dict.double_illuminate_) #local this.double_illuminate_ = check(params_dict.double_illuminate_, TYPES._bool_); #end #ifdef (params_dict.hollow_) #local this.hollow_ = check(params_dict.hollow_, TYPES._bool_); #end #ifdef (params_dict.no_shadow_) #local this.no_shadow_ = check(params_dict.no_shadow_, TYPES._bool_); #end #ifdef (params_dict.no_image_) #local this.no_image_ = check(params_dict.no_image_, TYPES._bool_); #end #ifdef (params_dict.no_reflection_) #local this.no_reflection_ = check(params_dict.no_reflection_, TYPES._bool_); #end #ifdef (params_dict.no_radiosity_) #local this.no_radiosity_ = check(params_dict.no_radiosity_, TYPES._bool_); #end #else #local this.texture_ = DEFAULT_TEXTURE; #end #end #macro ObjectModifiers_dump(this, indent_level) #debug concat(indent[indent_level], "instance of \"", this.class.classname, "\"\n") #debug concat(indent[indent_level], "{\n") #debug concat(indent[indent_level + 1], "texture : \n") #if (this._has_interior_texture) #debug concat(indent[indent_level + 1], "interior_texture : \n") #end #if (this._has_interior) #debug concat(indent[indent_level + 1], "interior : \n") #end #if (this._has_pigment) #debug concat(indent[indent_level + 1], "pigment : \n") #end #if (this._has_normal) #debug concat(indent[indent_level + 1], "normal : \n") #end #if (this._has_finish) #debug concat(indent[indent_level + 1], "finish : \n") #end #if (this._has_object_photons) dump(this.object_photons, indent_level + 1) #end #if (this._has_object_radiosity) dump(this.object_radiosity, indent_level + 1) #end #if (this._has_bounded_by) #debug concat(indent[indent_level + 1], "bounded_by : \n") #end #if (this._has_clipped_by) #debug concat(indent[indent_level + 1], "clipped_by : \n") #end #if (this._has_transform) #debug concat(indent[indent_level + 1], "transform : \n") #end #if (this.double_illuminate_) #debug concat(indent[indent_level + 1], "double_illuminate\n") #end #if (this.hollow_) #debug concat(indent[indent_level + 1], "hollow\n") #end #if (this.no_shadow_) #debug concat(indent[indent_level + 1], "no_shadow\n") #end #if (this.no_reflection_) #debug concat(indent[indent_level + 1], "no_reflection\n") #end #if (this.no_radiosity_) #debug concat(indent[indent_level + 1], "no_radiosity\n") #end #debug concat(indent[indent_level + 1], "commit() : ", this.commit, "\n") #debug concat(indent[indent_level], "}\n") #end #macro ObjectModifiers_commit(this) texture {this.texture_} // texture madatory, even reduced to a pigment (as default value) #if (this._has_interior_texture) interior_texture {this.interior_texture_} #end #if (this._has_pigment) pigment {this.pigment_} #end #if (this._has_normal) normal {this.normal_} #end #if (this._has_finish) finish {this.finish_} #end #if (this._has_interior) interior {this.interior_} #end #if (this._has_finish) finish {this.finish_} #end #if (this._has_object_photons) commit(this.object_photons) #end #if (this._has_object_radiosity) commit(this.object_radiosity) #end #if (this._has_bounded_by) bounded_by {this.bounded_by_} #end #if (this._has_clipped_by) clipped_by {this.clipped_by_} #end #if (this._has_transform) transform {this.transform_} #end #if (this.double_illuminate_) double_illuminate #end #if (this.hollow_) hollow #end #if (this.no_shadow_) no_shadow #end #if (this.no_image_) no_image #end #if (this.no_reflection_) no_reflection #end #if (this.no_radiosity_) no_radiosity #end #end // Convenience macros based on dictionary parameter (same as for constructors) #macro setmods(this, mods_dict) set(this, this.modifiers, new(ObjectModifiers,, mods_dict)) #end #macro setobjectphotons(this, object_photons_dict) set(this, this.modifiers.object_photons, new(ObjectPhotons,, object_photons_dict)) #end // Convenience macros based on objectitem parameter #macro settexture(this, texture_) set(this, this.modifiers.texture_, check(texture_, TYPES._texture_)) #local this.modifiers.pigment_ = None; #local this.modifiers._has_pigment = no; #local this.modifiers.normal_ = None; #local this.modifiers._has_normal = no; #local this.modifiers.finish_ = None; #local this.modifiers._has_finish = no; #end #macro setinteriortexture(this, texture_) set(this, this.modifiers.interior_texture_, check(texture_, TYPES._texture_)) #local this.modifiers._has_interior_texture = yes; #end #macro setpigment(this, pigment_) set(this, this.modifiers.pigment_, check(pigment_, TYPES._pigment_)) #local this.modifiers._has_pigment = yes; #end #macro setnormal(this, normal_) set(this, this.modifiers.normal_, check(normal_, TYPES._normal_)) #local this.modifiers._has_normal = yes; #end #macro setfinish(this, finish_) set(this, this.modifiers.finish_, check(finish_, TYPES._finish_)) #local this.modifiers._has_finish = yes; #end #macro settransform(this, transform_) set(this, this.modifiers.transform_, check(transform_, TYPES._transform_)) #local this.modifiers._has_transform = yes; #end #macro setclippedby(this, clipped_by_) set(this, this.modifiers.clipped_by_, check(clipped_by_, TYPES._object_)) #local this.modifiers._has_clipped_by = yes; #end #macro setdoubleilluminate(this) set(this, this.modifiers.double_illuminate_, true) #end #macro sethollow(this) set(this, this.modifiers.hollow_, on) #end #macro setnoshadow(this) set(this, this.modifiers.no_shadow_, true) #end #macro setnoimage(this) set(this, this.modifiers.no_image_, true) #end #macro setnoreflection(this) set(this, this.modifiers.no_reflection_, true) #end #macro setnoradiosity(this) set(this, this.modifiers.no_radiosity_, true) #end // ================================================ // == class Object ================================ #declare Object = class ( "Object", no, None, // No parent class array { // Public properties array mixed {"modifiers", TYPES._instance_, ObjectModifiers}, // Private properties array mixed {"_spawned", TYPES._bool_}, // private property array mixed {"_instance", TYPES._object_}, // private property }, array {"spawn"} // Virtual method (= not implemented) => should be implemented by child classes. ) //setvirtual(Object) #macro new_Object(this, optional params_dict) // params_dict ignored. #local this._spawned = false; #local this._instance = None; #local this.modifiers = new(ObjectModifiers,,); #end #macro Object_dump(this, indent_level) dump(this.modifiers, indent_level) #debug concat(indent[indent_level], "spawn() : ", this.spawn, "\n") #if (this._spawned) #debug concat(indent[indent_level], "==> spawned\n") #end #end // ================================================ // == class Sphere ================================ #declare Sphere = class ( "Sphere", yes, Object, array { array mixed {"center", TYPES._vector_}, array mixed {"radius_", TYPES._float_} }, , // No methods ) // Default constructor #macro new_Sphere(this, optional params_dict) super(this,,) #local this.center = check(tovector(params_dict.center), TYPES._vector_); #local this.radius_ = check(params_dict.radius_, TYPES._float_); #end // Copy constructor #macro new_1_Sphere(this, sphere_instance) #if (!instanceof(sphere_instance, Sphere)) #error concat ("Sphere copy constructor : expected a \"Sphere\" object (or derived), got \"", sphere_instance.class.classname, "\".") #end super(this,,) // Copy properties #local this.center = sphere_instance.center; #local this.radius_ = sphere_instance.radius_; #undef this.modifiers #local this.modifiers = sphere_instance.modifiers; #end #macro Sphere_dump(this, indent_level) #debug concat(indent[indent_level], "instance of \"", this.class.classname, "\"\n") #debug concat(indent[indent_level], "{\n") #debug concat(indent[indent_level + 1], "center : ", tostring(this.center, TYPES._vector_),"\n") #debug concat(indent[indent_level + 1], "radius : ", tostring(this.radius_, TYPES._float_),"\n") Object_dump(this, indent_level + 1) #debug concat(indent[indent_level], "}\n") #end #macro Sphere_spawn(this) spawn_object (this, sphere { this.center, this.radius_ commit(this.modifiers) }) #end // ================================================ // == class Box =================================== #declare Box = class ( "Box", yes, Object, // parent class array { array mixed {"ll", TYPES._vector_}, array mixed {"ur", TYPES._vector_} }, , // No additional methods ) // Default constructor #macro new_Box(this, optional params_dict) super(this,,) // Seet main properties #local this.ll = check(tovector(params_dict.ll), TYPES._vector_); #local this.ur = check(tovector(params_dict.ur), TYPES._vector_); #end // Copy constructor #macro new_1_Box(this, box_instance) #if (!instanceof(box_instance, Box)) #error concat ("Box copy constructor : expected a \"Box\" object (or derived), got \"", box_instance.class.classname, "\".") #end super(this,,) // Copy all properties #local this.ll = check(tovector(box_instance.ll), TYPES._vector_); #local this.ur = check(tovector(box_instance.ur), TYPES._vector_); #undef this.modifiers #local this.modifiers = box_instance.modifiers; #end #macro Box_dump(this, indent_level) #debug concat(indent[indent_level], "instance of \"", this.class.classname, "\"\n") #debug concat(indent[indent_level], "{\n") #debug concat(indent[indent_level + 1], "lower-left : ", tostring(this.ll, TYPES._vector_),"\n") #debug concat(indent[indent_level + 1], "upper-right : ", tostring(this.ur, TYPES._vector_),"\n") Object_dump(this, indent_level + 1) #debug concat(indent[indent_level], "}\n") #end #macro Box_spawn(this) spawn_object (this, box { this.ll, this.ur commit(this.modifiers) }) #end // ================================================ // == class Cylinder ============================== #declare Cylinder = class ( "Cylinder", yes, Object, // Parent class array { array mixed {"base", TYPES._vector_}, array mixed {"cap", TYPES._vector_}, array mixed {"radius_", TYPES._float_}, array mixed {"open_", TYPES._bool_} }, , // No additional methods ) // Default constructor #macro new_Cylinder(this, optional params_dict) super(this,,) // Set main properties #local this.base = check(tovector(params_dict.base), TYPES._vector_); #local this.cap = check(tovector(params_dict.cap), TYPES._vector_); #local this.radius_ = check(params_dict.radius_, TYPES._float_); // Set default values for other properties #local this.open_ = false; #end // Copy constructor #macro new_1_Cylinder(this, cylinder_instance) #if (!instanceof(cylinder_instance, Cylinder)) #error concat ("cylinder_instance copy constructor : expected a \"Cylinder\" object (or derived), got \"", cylinder_instance.class.classname, "\".") #end super(this,,) // Copy all properties #local this.base, check(tovector(cylinder_instance.base), TYPES._vector_)) #local this.cap, check(tovector(cylinder_instance.cap), TYPES._vector_)) #local this.radius_, check(cylinder_instance.radius_, TYPES._float_)) #local this.open_ = cylinder_instance.open_; #undef this.modifiers #local this.modifiers = cylinder_instance.modifiers; #end #macro new_2_Cylinder(this, optional params_dict) super(this,,) // Set properties according to signature #local this.base, check(tovector(params_dict.base), TYPES._vector_)) #local this.cap, check(tovector(params_dict.cap), TYPES._vector_)) #local this.radius_, check(params_dict.radius_, TYPES._float_)) #local this.open_, check(params_dict.open_, TYPES._bool_)) #end #macro Cylinder_dump(this, indent_level) #debug concat(indent[indent_level], "instance of \"", this.class.classname, "\"\n") #debug concat(indent[indent_level], "{\n") #debug concat(indent[indent_level + 1], "base : ", tostring(this.base, TYPES._vector_),"\n") #debug concat(indent[indent_level + 1], "cap : ", tostring(this.cap, TYPES._vector_),"\n") #debug concat(indent[indent_level + 1], "radius : ", tostring(this.radius_, TYPES._float_),"\n") #debug concat(indent[indent_level + 1], "open : ", tostring(this.open_, TYPES._bool_),"\n") Object_dump(this, indent_level + 1) #debug concat(indent[indent_level], "}\n") #end #macro Cylinder_spawn(this) spawn_object (this, cylinder { this.base, this.cap, this.radius_ commit(this.modifiers) #if (this.open_) open #end }) #end // ================================================ // == class Torus ================================= #declare Torus = class ( "Torus", yes, Object, // parent class array { array mixed {"major", TYPES._float_}, array mixed {"minor", TYPES._float_}, array mixed {"spindle_type", TYPES._int_}, array mixed {"sturm_", TYPES._bool_} }, , // No additional methods ) #declare SpindleTypes = dictionary { .dicttype : "Enum", .UNION : 0, // default .MERGE : 1, .DIFFERENCE : 2, .INTERSECTION : 3, ._names : array {"union", "merge", "difference", "intersection"} } // Default constructor #macro new_Torus(this, optional params_dict) super(this,,) // Set main properties #local this.major = check(params_dict.major, TYPES._float_); #local this.minor = check(params_dict.minor, TYPES._float_); // Set default values for other properties #local this.spindle_type = SpindleTypes.UNION; #local this.sturm_ = false; #end #macro new_1_Torus(this, torus_instance)Cylinder #if (!instanceof(torus_instance, Torus)) #error concat ("torus_instance copy constructor : expected a \"Torus\" object (or derived), got \"", torus_instance.class.classname, "\".") #end super(this,,) // Copy all properties #local this.major = check(tovector(torus_instance.major), TYPES._vector_); #local this.minor = check(tovector(torus_instance.minor), TYPES._vector_); #local this.spindle_type = check(torus_instance.spindle_type, TYPES._int_); #local this.sturm_ = check(torus_instance.sturm_, TYPES._bool_); #end #macro new_2_Torus(this, optional params_dict) super(this,,) // Set properties according to signature #local this.major = check(tovector(params_dict.major), TYPES._vector_); #local this.minor = check(tovector(params_dict.minor), TYPES._vector_); #local this.spindle_type = check(params_dict.spindle_type, TYPES._int_); // Set default values for other properties #local this.sturm_ false; #end #macro new_3_Torus(this, optional params_dict) super(this,,) // Set properties according to signature #local this.major = check(tovector(params_dict.major), TYPES._vector_); #local this.minor = check(tovector(params_dict.minor), TYPES._vector_); #local this.spindle_type = check(params_dict.spindle_type, TYPES._int_); #local this.sturm_ = check(params_dict.sturm_, TYPES._bool_); #end #macro Torus_dump(this, indent_level) #debug concat(indent[indent_level], "instance of \"", this.class.classname, "\"\n") #debug concat(indent[indent_level], "{\n") #debug concat(indent[indent_level + 1], "major : ", tostring(this.major, TYPES._vector_),"\n") #debug concat(indent[indent_level + 1], "minor : ", tostring(this.minor, TYPES._vector_),"\n") #debug concat(indent[indent_level + 1], "spindle_type : ", enum_name(SpindleTypes, this.spindle_type)"\n") #debug concat(indent[indent_level + 1], "sturm ", tostring(this.sturm_, TYPES._bool_),"\n") Object_dump(this, indent_level + 1) #debug concat(indent[indent_level], "}\n") #end #macro Torus_spawn(this) spawn_object (this, torus { this.major, this.minor #switch (this.spindle_type) // UNION is the default : no need to make it explicit. #case (SpindleTypes.MERGE) merge #break #case (SpindleTypes.DIFFERENCE) difference #break #case (SpindleTypes.INTERSECTION) intersection #break #end commit(this.modifiers) #if (this.sturm_) sturm #end }) #end // ================================================ #version SLOPE_OBJECTS_INC; #end