Overview

The RoseDesign class manages EXPRESS-defined RoseObject instances. Each design contains a cluster of STEP data objects. Data objects can only be read from or written to secondary storage in RoseDesign clusters. Designs can be read and written STEP Part 21 file format.

A RoseDesign is a RoseObject which contains a collection of STEP data objects, but can never contain another design.

RoseDesign Constructor

RoseDesign(
	const char * design_name,
	const char * schema_name
	);

RoseDesign(
	const char * design_name,
	RoseDesign * schema = NULL
	);

There are two versions of the design object constructor. Both versions require a name for the design. The names of designs must be unique in memory. For example, an application could not create two designs named widget. The name is used as the basis for the filename when the design is written to secondary storage. The new design does not contain any objects.

Every design must also has associated schemas which provide the EXPRESS definitions for the objects within a design. When an application uses early-bound classes, each class knows it's schema, but when doing late-bound programming, the pnewInstance() and findDomain() functions must search through a list of schemas to find EXPRESS definitions.

The constructors takes an optional schema by name or pointer. Additional ones can be added with addSchema(). An early-bound application does not need to explicitly set the schemas unless it also does late-bound calls. If no schema is provided, the schema of the built-in C++ classes will be assigned to the design. The STEP Merged AP and IFC BIM libraries support multiple schemas in a single class library, so they have separate functions to indicate which one you are using.

Designs should be created with the new operator. The pnew operator may also be used, but it does the same thing as the new operator.

The example below creates a new design and sets it to be the default design.

RoseDesign * d = new RoseDesign (gizmo,config_control_design);

See Also

Creating and Deleting Design Objects

RoseDesign Destructor

~RoseDesign();

A design may be removed from memory using rose_move_to_trash() followed by rose_empty_trash() or by using the C++ delete operator. When a design is deleted, all data objects within it are also deleted. Using the delete operator may result in dangling references to the deleted data objects. To simply delete all data objects within a design, use the emptyYourself() function.

RoseDesign * design;

rose_move_to_trash (design);  /* schedule for deletion */
rose_empty_trash();           /* safe deletion */

design-> emptyYourself();   /* delete all data objects */
delete design;              /* delete design and all data objects */

See Also

Creating and Deleting Design Objects;

addName()

void RoseDesign::addName(
	const char * obj_name,
	RoseObject * obj
	);

Each design object stores a mapping from names to persistent objects. The addName() function will add or replace a entry in this mapping. An object can appear in the mapping under more than one name, but a name can only correspond to one object.

Older STEP Part 21 files do not support object naming, but the third edition of the Part 21 spec has an ANCHOR section that maps into object names.

The following example shows how an application can give names to some objects and then use those names to find the objects again later.

/* Create a design and some point objects. */
RoseDesign * d = new RoseDesign (tutorial1);
Point * point1 = pnewIn(d) Point;
Point * point2 = pnewIn(d) Point;
Point * point3 = pnewIn(d) Point;

d-> addName (top,    point1);
d-> addName (side,   point2);
d-> addName (bottom, point3);

We can use the names to search for the objects. Use the ROSE_CAST() macro to convert the pointer from RoseObject* to Point*:

Point * top =    ROSE_CAST (Point,d->findObject (top));
Point * side =   ROSE_CAST (Point,d->findObject (side));
Point * bottom = ROSE_CAST (Point,d->findObject (bottom));

See Also

Objects by Name; RoseDesign::findObject(); RoseDesign::nameTable(); RoseDesign::removeName()

addSchema()

void addSchema(
	RoseDesign * schema
	);

void addSchema(
	const char * schema_name
	);

The addSchema() function appends to the list of schemas kept by each design. These EXPRESS definitions determine the types of instances allowed in a design. Schema names are written to Part 21 files in the FILE_SCHEMA header section entity. The first version accepts a pointer to a schema design object, while the other accepts the name of the schema. If the schema is not in memory, it will be read in using the RoseInterface::findDesign() function.

The following examples create a design and then add several schemas to it. The resulting designs can use definitions from either AP203 or a local extension schema.

RoseDesign * design;

design = new RoseDesign (gizmo);
design-> addSchema (config_control_design);  /* add AP203 schema */
design-> addSchema (local_extensions);       /* add local schema */

The following example does the same thing, but uses findDesign() to find the schemas first:

RoseDesign * design;
RoseDesign * cc_schema;
RoseDesign * local_schema;

design = new RoseDesign (gizmo);
cc_schema =    ROSE.findDesign (config_control_design);*/
local_schema = ROSE.findDesign (local_extensions);*/

design-> addSchema (cc_schema);      /* add AP203 schema */
design-> addSchema (local_schema);   /* add local schema */

See Also

EXPRESS Data Dictionary; RoseDesign::findDomain(); RoseDesign::schemas(); RoseDesign::useSchema()

clrModified()

void clrModified();

The clrModified() function sets design to indicate that no changes have been made since it was last written to secondary storage. The RoseInterface::saveWorkspace() operation uses this information to determine which designs must be written to disk.

RoseDesign * design;

if (design-> isModified()) {
    printf (Design has been changed\n);
    design-> clrModified();
}

See Also

RoseDesign::isModified(); RoseDesign::setModified(); RoseInterface::saveWorkspace()

deleteEidIndex()

The deleteEidIndex() function frees the memory that is allocated to hold the entity instance id index that is built the first time you call the findByEntityId() function.

dflt_section()

RoseDesignSection * dflt_section();

void dflt_section(
	RoseDesignSection * new_section
	);

The dflt_section() functions get and set the default section for a design. Normal data objects created by pnewIn (RoseDesign*) are placed in this default section. The sections of a design roughly correspond to the sections of a Part 21 physical file. One holds data objects, one holds file header objects, and one holds internal system objects. Newer third-edition STEP files may also have a section that holds external references.

The dflt_section() function never returns null. If the default section would be null, the function searches for the first section of type ROSE_SECTION_DATA in the design. If the design does not have a section of that type, one will be created.

Create objects in a different section explicitly with pnewIn (RoseDesignSection*), or you can change thie default section to something else.

See Also

Design Sections; RoseDesign::sections()

display()

void display();

The display() function will recursively print the contents of an entire design object on stdout using the ROSE text working form. This function uses the RoseInterface traversal functions so it should not be used in an existing traversal.

The following fragment code fragment creates some graphics objects and then shows the use of the display() function to print the contents resulting design:

/* Create a design to store the picture */
RoseDesign * d = new RoseDesign (tutorial1);

/* Create some point, line and other objects. */
Point * point1 = pnewIn(d) Point;
point1->x (1.0);
point1->y (0.0);
Point * point2 = pnewIn(d) Point (2.5, 4.0);
Point * point3 = pnewIn(d) Point (5.0, 0.0);

/* Create a Line Object */
Line * line = pnewIn(d) Line (point1, point2);

/* Create a Circle with Center (0,0), radius 1.5 */
Circle * circle1 = pnewIn(d) Circle (1.5, pnewIn(d) Point (0.0, 0.0));

/* Create a Text Object centered at point3 */
Text * text = pnewIn(d) Text (A Little Picture, point3);

/* Display all STEP Objects in the picture */
d-> display();

The terminal output from the display is shown below. The first component of the display is a table of 160bit object identifier prefixes. The identifiers themselves are shown in the shorthand <xxx-yyy> form, with an index into the table of prefixes and then a suffix.

ROSE_OIDS (
	(0 = 0x027230515C000030D9A7AB00005E2E0200000000)
)

Next comes some information about the design object, including it's name and system data like the name table and list of schemas.

ROSE_DESIGN (RoseDesign
	name: tutorial1
	root: $
	keyword_table: $
	name_table: $
	schemas: $
)

Finally, the data objects are written. The objects are written in a recursive manner, so the contents of attributes are shown in place, as seen with the center point of the circle. If an object has already been shown, the display just lists the OID of the object, as seen with both endpoints of the line.

STEP_OBJECTS (
	(<0-0> Point
		x: 1
		y: 0)
	(<0-1> Point
		x: 2.5
		y: 4)
	(<0-2> Point
		x: 5
		y: 0)
	(<0-3> Line
		enda: <0-0>
		endb: <0-1>)
	(<0-4> Circle
		radius: 1.5
		center: (<0-5> Point
			x: 0
			y: 0))
	(<0-6> Text
		label: A Little Picture
		center: <0-2>)
)

emptyYourself()

void emptyYourself();

The emptyYourself() function deletes all data objects in the design. This may result in dangling references to the deleted objects. To delete everything without dangling references, use rose_move_to_trash() to move the entire design to the trash.

This removes all data sections. The header and system sections are not deleted, so the design will still have schema and Part 21 header information. The object name table is removed by this operation, since it contains references to objects in the data sections.

RoseDesign * design;

design-> emptyYourself();   /* delete all data objects */
delete design;              /* delete entire design */

/* better way to remove an entire design */
rose_move_to_trash (design);
rose_empty_trash();

See Also

Deleting Objects

fileArchiveMember()

const char * fileArchiveMember();

void fileArchiveMember (
	const char * nm
	);

The fileArchiveMember() function gets and sets the path within an archive, such as a ZIP file, that a design was read from or will be written to. If null, a default member name will be used when writing. For Part 21 Edition 3 ZIP files, "ISO-10303-21.txt" is the default member name that is called out in the standard.

fileDirectory()

const char * fileDirectory();

void fileDirectory(
	const char * dir_name
	);

The fileDirectory() function returns the directory portion of the file path(). The string typically ends with a path separator (forward or backslash). Changing the directory also changes the path() value. You can pass in a string without a trailing separator - one will be added if needed. A directory can contain the full range of international characters encoded as a UTF-8 string.

See fileExtension() for an example.

fileExtension()

const char * fileExtension();

void fileExtension(
	const char * ext
	);

The fileExtension() function returns the extension portion of the file path(). The string typically contains the dot separator. For example, a STEP file returns .stp. Changing the extension also changes the path() value. You can pass in a string without a dot separator - one will be added if needed.

If you create a design with a name that does not have an extension, it will be given .stp as a default extension. You may want to change this to ifc if you are working with IFC data.

If you call format() to change the file format, the extension may be changed to an extension appropriate for the new format.

// path = gizmo.stp
RoseDesign * d = new RoseDesign (gizmo);

// path = /home/database/gizmo.stp
d-> fileDirectory (/home/database);

// path = /home/database/gizmo.foo
d-> fileExtension (foo);

See Also

Reading and Writing Design Objects; RoseDesign::save()

findByEntityId()

RoseStructure * findByEntityId(
	unsigned long id
	);

The findByEntityId() function searches a design for an object with a given entity instance ID. The first time this function is called on a design, is creates an index which makes all subsequent calls very efficient. This index can be deleted (to save memory) by calling the deleteEidIndex() function.

RoseDesign * design;

RoseObject * obj = design->findByEntityId(453);

findComplexDomain()

RoseDomain * findComplexDomain (
	ListOfRoseDomain * supers
	);
RoseDomain * findComplexDomain (
	ListOfString * super_names
	);

The findComplexDomain() function searches for the domain that describes the EXPRESS AND/OR combination for a list of domains. Complex domains and C++ classes for them can be created at build time using the EXPRESS compiler and the ANDOR() working set option. At run time, domain object is created for a combination if needed. If a list of strings is provided, the domains will be located using findDomain().

The following example shows an attempt to find a domain for an EXPRESS AND/OR combination of the brep_with_voids and facetted_brep entities.

RoseDomain * dom;
RoseDesign * design;
ListOfRoseDomain supers;

supers.add (design-> findDomain (brep_with_voids)); 
supers.add (design-> findDomain (facetted_brep)); 
dom = design-> findComplexDomain (&supers)

/* create a new brep_with_voids_and_facetted_brep instance */
obj-> design-> pnewInstance (dom);

See Also

Creating Objects; Searching for Domains; RoseDesign::pnewInstance()

findDomain()

RoseDomain * findDomain(
	const char * domain_name
	);

The findDomain() function searches the schemas of a design for a RoseDomain object with the given name. RoseDomain objects are compiled representations of EXPRESS definitions. The function will search each schema of the design, as well as the schemas of those schemas, and so on. If no domain is found, the function will return null. The names of the EXPRESS definitions are not case sensitive.

The following example creates a new design that uses a picture schema, and then creates some cartesian point objects within the design.

RoseDesign * design;
RoseDomain * dom;
RoseObject * obj;

design = new RoseDesign (gizmo, picture);

dom = design-> findDomain (point);   /* entity type in picture schema*/
obj = design-> pnewInstance (dom);     /* create a new point instance */

See Also

Creating Objects; Searching for Domains; RoseDesign::pnewInstance()

findObject()

RoseObject * findObject(
	const char * obj_name
	);

RoseObject * findObject(
	RoseOID oid
	) 

The findObject() functions search a design for individual data objects. The first version searches the name table of the design for an entry with the specified name. If a match is not found, the function returns null.

The second version searches the design for an object with the given object identifier. The library internals use this routine, but most applications will have little use for it since OIDs are a low-level way of locating persistent objects.

The following example shows how an application can give names to some objects and then use those names to find the objects again later.

/* Create a design and some point objects. */
RoseDesign * d = new RoseDesign (tutorial1);
Point * point1 = pnewIn(d) Point;
Point * point2 = pnewIn(d) Point;
Point * point3 = pnewIn(d) Point;

d-> addName (top,    point1);
d-> addName (side,   point2);
d-> addName (bottom, point3);

Later on in the application, we can use the names to search for the objects. Notice the use of ROSE_CAST() to convert the pointer from RoseObject* to Point*:

Point * top =    ROSE_CAST (Point,d->findObject (top));
Point * side =   ROSE_CAST (Point,d->findObject (side));
Point * bottom = ROSE_CAST (Point,d->findObject (bottom));

Since findObject() can only return RoseObject*, a cast is usually required to convert the pointer to a useful type.

See Also

Pointer Type Casting; Objects by Name; ROSE Universal Object Identifiers (OIDS); RoseDesign::addName()

findObjects()

RoseAggregate * findObjects(
	RoseAggregate * list_to_fill = NULL
	);

RoseAggregate * findObjects(
	RoseDomain * domain,
	RoseAggregate * list_to_fill = NULL
	);

The findObjects() functions examine all objects in a design and populate a list with those which satisfy C++ class or ROSE domain criteria. These functions are simply a wrappers around a cursor, and it is usually better to just use a cursor directly since they do not require intermediate storage.

The functions expect an aggregate object to hold the appended results, which can accumulate over several searches. If no aggregate is passed in, a ListOfRoseObject will be created by the function. It is your responsibility to free this object when it is no longer needed.

Both functions select object that match the type of the aggregate (or subtypes). For example, passing a ListOfPoint selects objects matching the C++ class Point or its subclasses . The second version also takes a RoseDomain object. In this case, objects must be an instance of the EXPRESS type given by the domain as well as the C++ class restrictions implied by the return list. The domain should be at least as specific as the C++ class constraints.

The following example finds all cartesian points in a design. Note the use of an aggregate on the stack. The ListOfPoint access functions insure the correct pointer type, so additional casting is not needed.

RoseDesign * design;
ListOfPoint points;
unsigned i, sz;

design-> findObjects (&points);
for (i=0, sz=points.size(); i<sz; i++) {
    Point * pt = points-> get(i);
    /* do something with the point */
}


// Alternatively, more efficient to just use a RoseCursor
RoseCursor objs;
RoseObject * obj;

objs.traverse(design);
objs.domain(ROSE_DOMAIN(Point));

while ((obj=objs.next()) != 0) {
    Point * pt = ROSE_CAST(Point,obj);
    /* do something with the point */
}

The second form of the function can find a more specific type of point. The results are still placed in a ListOfPoint:

RoseDesign * design;
List (Point) points;
unsigned i, sz;

design-> findObjects (ROSE_DOMAIN(SpecialPoint), &points);
for (i=0, sz=points.size(); i<sz; i++) {
    Point * pt = points-> get(i);
    /* do something with the special points */
}


// A RoseCursor has the same basic code
RoseCursor objs;
RoseObject * obj;

objs.traverse(design);
objs.domain(ROSE_DOMAIN(SpecialPoint));

while ((obj=objs.next()) != 0) {
    SpecialPoint * pt = ROSE_CAST(SpecialPoint,obj);
    /* do something with the point */
}

firstSchema()

RoseDesign * firstSchema ();

The firstSchema() functions returns the first schema in the list of schemas kept by each design. This list of schemas determine which EXPRESS definitions are available to create instances with. Since many designs only have one schema, this function is a shortcut to retrieving the entire list. If no schemas are present, it returns the "keystone" schema of built-in types.

The following example prints the name of the first schema for a design.

    RoseDesign * design;
    RoseDesign * schema;
    
    schema = design-> firstSchema();
    printf (Design uses %s schema\n, schema-> name());

See Also

EXPRESS Data Dictionary; RoseDesign::schemas()

format()

char * format();

void format(
	const char * file_format
	);

The format() function gets and sets the file format that is used to write objects to secondary storage when calling RoseDesign::save(). The following format strings are recognized. Extension libraries may add others.

step
p21 (alias)
The default format. The STEP Part 21 ASCII exchange file format defined in ISO 10303-21. Unless otherwise specified, files are given the ".stp" extension.

step-zip
p21-zip (alias)
Zip-compressed Part 21 data as above. Unless otherwise specified, files are given the ".stp" extension.

p28
The STEP Part 28 XML file format defined in ISO 10303-28. Files are zip-compressed to reduce size. This requires linking with the rosexml and rosemath libraries. Unless otherwise specified, files are given the ".p28" extension.

p28-raw
The STEP Part 28 XML file format as above, but written without any compression. This requires linking with the rosexml and rosemath libraries. Unless otherwise specified, files are given the ".xml" extension.

rosebin
binary (alias)
ROSE binary working form. This is a machine-independent binary format. Unless otherwise specified, files are given the ".rose" extension.

rosetxt
rose (alias)
ROSE ASCII working form. The least efficient but most readable format. Also the most resistant to schema changes. Unless otherwise specified, files are given the ".rose" extension.

The following example saves a design object in a number of different formats.

RoseDesign * design;

design-> format (p21);     /* save as step part21 file (default) */
design-> save();

design-> format (rosebin); /* save as binary rose file */
design-> save();

design-> format (rosetxt);     /* save as text rose file */
design-> save();

header_description()

file_description * header_description();

The header section information from STEP Part 21 exchange files contain several descriptive objects. The file description object describes the contents of the exchange file, along with the version of ISO 10303-21 that was used to create it. The EXPRESS definition for this object is shown below:

ENTITY file_description; 
    description             : LIST [1:?] OF STRING (256);
    implementation_level    : STRING (256);
END_ENTITY;

The header_description() returns an instance of the file description object. When you create a new design object, the header information is not automatically created. The initialize_header() function will create the object if necessary, and initialize the implementation_level field.

/* create the design */ 
/* use Part 21 when writing it out */ 
design = new RoseDesign (camshaft, config_control_design);
design-> format (step);

/* fill in the header information */
design-> initialize_header();

/* implementation_level field is taken care of by the
 * tool kit.     
 */ 
design -> header_description()-> description ()->
    add (This file contains the design for widgets);

See Also

Header Section Information; RoseDesign::header_name(); RoseDesign::initialize_header(); RoseDesign::schemas()

header_name()

file_name * header_name();

The header section information from STEP Part 21 exchange files contain several descriptive objects. The file name object provides human-readable information about the exchange structure. It describes the person and systems that created the file. The EXPRESS definition for this object is shown below:

ENTITY file_name;
    name                  : STRING (256);
    time_stamp            : STRING (256);
    author                : LIST [1:?] OF STRING (256);
    organization          : LIST [1:?] OF STRING (256);
    preprocessor_version  : STRING (256); 
    originating_system    : STRING (256);
    authorisation         : STRING (256); 
END_ENTITY;

The header_name() returns an instance of the file name object. When you create a new design object, the initialize_header() function should be used to create the header information. This function will initialize the name, time stamp, and preprocessor version fields. The ROSE library inserts an updated time stamp string whenever the file is written.

/* create the design */ 
/* use Part 21 when writing it out */ 
design = new RoseDesign (camshaft, config_control_design);
design-> format (step);

/* fill in the header information */
design-> initialize_header();

/* name, time_stamp, and preprocessor_version fields     
 *  are taken care of by the tool kit.
 */ 
design-> header_name()-> originating_system (MonkeyCad 2.3);
design-> header_name()-> author ()-> add (Sam Simian);
design-> header_name()-> organization()-> add (Monkey International);
design-> header_name()-> authorisation (Sam's Boss);

See Also

Header Section Information; RoseDesign::header_description(); RoseDesign::initialize_header(); RoseDesign::schemas()

header_section()

RoseDesignSection * header_section();

void header_section(
	RoseDesignSection * new_section
	);

Each design may contain several sections, one or more for the data objects, one for physical file header objects, and one for internal system objects. These sections correspond to the sections of a Part 21 physical file and are represented by instances of the RoseDesignSection class.

The header_section() functions get and set the header section for a design. This section contains the file_name and file_description entities from a Part 21 header section. The file_schema entity is handled by the library and is not present in this section.

The header_section() function never returns null. If the header section would be null, the function searches for the first section of type ROSE_SECTION_HEADER in the design. If the design does not have a section of that type, one will be created.

The header section can be traversed using a RoseCursor. This is redundant since the header_name() and header_description() functions already provide these objects:

RoseDesign * design;
RoseCursor objs;
RoseObject * obj;

all_objects.traverse (design-> header_section());
while (obj = all_objects.next()) {
    /* do something with the header object */
}

See Also

Design Sections; Header Section Information; RoseDesign::dflt_section(); RoseDesign::header_description(); RoseDesign::header_name(); RoseDesign::sections()

initialize_header()

void initialize_header();

The header section information from STEP Part 21 exchange files contain several descriptive objects. When you create a new design object, the initialize_header() function should be used to create file header and file description information. Refer to the header_description() and header_name() functions for more details about the individual objects.

RoseDesign * design;

/* create the design */ 
design = new RoseDesign (camshaft, config_control_design);
design-> initialize_header();   /* fill in header information */

See Also

Header Section Information; RoseDesign::header_description(); RoseDesign::header_name(); RoseDesign::schemas()

isModified()

RoseBoolean isModified();

The modified flag indicates whether any changes have been made to the design object since it was last written to secondary storage. The RoseInterface::saveWorkspace() operation uses this flag to determine which designs must be written to disk. The isModified() function returns the value of this flag.

RoseDesign * design;

if (design-> isModified()) {
    printf (Design has been changes\n);
    design-> clrModified();
}

See Also

RoseDesign::clrModified(); RoseDesign::setModified()

isSchema()

RoseBoolean isSchema();

The isSchema() function returns a boolean value indicating whether a design object contains compiled EXPRESS definitions. EXPRESS definitions are represented as instances of RoseDomain and RoseAttribute objects.

RoseDesign * design;

if (design-> isSchema()) {
    printf (Design is a compiled EXPRESS schema\n);
}

See Also

EXPRESS Data Dictionary; RoseDesign::schemas()

isTrashed()

RoseBoolean isTrashed();

The isTrashed() function returns a boolean value indicating whether a design object has been marked for deletion by calling rose_move_to_trash(). When the rose_empty_trash() function is called, designs that are marked for deletion will be removed along with their contents.

RoseDesign * design;

rose_move_to_trash (design);
if (design-> isTrashed()) {
    printf (Design %s will be deleted\n, design-> name());
}
rose_empty_trash();

name()

const char * name();

void name(
	const char * new_name
	);

The name() access function returns the base file name, without directory or extension, of the complete file path. The update function accepts a full or partial file path. It will only change the fileDirectory() if one is given. It will change the fileExtension() if given and will add a default one if neither the string nor the design have one.

The design constructor calls name() to initialize the filename for the design. Use path() to set the complete file path explicitly, without any additional behavior.

The path() access function returns the full path that is used when reading and writing designs. The name and path can include the full range of international characters encoded as UTF-8 strings.

// name = gizmo, path = gizmo.stp
RoseDesign * d = new RoseDesign (gizmo);  

// name = foobar, path = foobar.stp
d-> name(foobar);

// name = there, path = /hello/there.new
d-> name(/hello/there.new);

// Only changes the name part, dir and ext stay the same
// name = baz, path = /hello/baz.new
d-> name(baz);

// Changes the name and ext, dir stays the same
// name = cheese, path = /hello/cheese.stp
d-> name(cheese.stp);

nameTable()

DictionaryOfRoseObject* nameTable();

void nameTable(
	DictionaryOfRoseObject * nt
	);

These functions get and set the internal object dictionary that the design uses as a name index for its contents. This is the dictionary searched by the findObject() function. This dictionary is created automatically, so applications should never need to set the name table.

Originally, STEP Part 21 files could not support object names, but edition three now has an ANCHOR section that can hold these. To write these in a file, you must turn on third edition support with RoseP21Writer::max_spec_version().

The following example prints the contents of a design's name table:

RoseDesign * design;
DictionaryOfRoseObject * names;
unsigned i, sz;

names = design-> nameTable();
for (i=0, sz=names->size(); i<sz; i++) {
    printf (Contains an object called %s\n,
	    names-> listOfKeys()-> get(i));
}

See Also

RoseDesign::addName(); RoseDesign::findObject(); RoseDesign::removeName()

path()

const char * path();

void path(
	const char * dir_name
	);

The path() functions get and set the full file path for reading and writing the design. This is the complete file name and directory that the design was read from and will be written to. Use path() to change the complete file path, and name() to change the filename while leaving the directory unchanged.

You can work with individual components of the path using the name(), fileDirectory(), and fileExtension() functions. The path can include the full range of international characters encoded as a UTF-8 string.

// name = gizmo, path = gizmo.stp
RoseDesign * d = new RoseDesign (gizmo);  

// name = foobar, path = foobar
d-> path(foobar);

// name = there, path = /hello/there.new
d-> path(/hello/there.new);

// name = baz, path = baz
d-> path(baz);

// name = cheese, path = cheese.stp
d-> path(cheese.stp);

pnewInstance()

RoseObject * pnewInstance(
	const char * domain_name,
	unsigned sz = 0
	);

RoseObject * pnewInstance(
	RoseDomain * domain,
	unsigned sz = 0
	);

The pnewInstance() functions create new data objects within a design. The EXPRESS type of the new objects are given by a RoseDomain object. The domain can be specified by name or by pointer. If a name is specified, the findDomain() function will be used to search the schemas of the design for a matching domain instance. The name of domains are not case sensitive.

The size parameter is used when creating instances of aggregates. The size specifies the initial size in the case of arrays, or that capacity in the case of lists, sets, and bags. Setting the size at creation time avoids resizing later on.

The following example creates a new design that uses a picture schema, and then uses the pnewInstance() function to create some cartesian point objects within the design.

RoseDesign * design;
RoseDomain * dom;
RoseObject * obj;

design = new RoseDesign (gizmo, picture);

obj = design-> pnewInstance (point); /* create a new instance */

dom = design-> findDomain (point);   /* entity def in schema*/
obj = design-> pnewInstance (dom);     /* create a new instance */

The following example creates a list of strings with a capacity of 20, and then adds some strings. Lists resize automatically, so the capacity argument could be omitted.

RoseObject * strings = design-> pnewInstance (ListOfString, 20);

strings->putString (string zero, 0);
strings->putString (string one, 1);
strings->putString (string two, 2);

See Also

Creating Objects; RoseDesign::findDomain(); RoseObject::Operator new / pnew / pnewIn

reference_section()

RoseDesignSection * reference_section();

void reference_section(
	RoseDesignSection * new_section
	);

The reference_section() functions get and set the reference section for a design. The reference section holds RoseReference objects that each hold the URL and resolved object for an external reference. Only third-edition Part 21 files will have these references.

The reference_section() function never returns null. If no value has been assigned, the function searches for a section with a type of ROSE_SECTION_REFERENCE in the design. If none exists, one will be created.

The reference section can be traversed using a RoseCursor

RoseDesign * design;
RoseCursor objs;
RoseObject * obj;

objs.traverse (design-> reference_section());
objs.domain (ROSE_DOMAIN(RoseReference));
while ((obj = objs.next()) != 0) {
    /* do something with the reference */
}

See Also

Design Sections; References Between Data Sets

removeName()

RoseObject * removeName(
	const char * obj_name
	);

The removeName() function removes the name assignment from the object dictionary and returns a pointer to the object that was associated with the name. If no object was associated with that name the function will return null.

STEP Part 21 files do not support this information. You must save your design as a ROSE working form file in order to preserve this information.

The following example shows how an application can associate names with some objects and then use the removeName() function to eliminate the association:

/* Create a design and some point objects. */
RoseDesign * d = new RoseDesign (tutorial1);
Point * point1 = pnewIn(d) Point;
Point * point2 = pnewIn(d) Point;
Point * point3 = pnewIn(d) Point;

d-> addName (top,    point1);
d-> addName (side,   point2);
d-> addName (bottom, point3);

d-> removeName (top);

After this code example, point1 is no longer associated with the name top. The object is otherwise unaffected.

See Also

RoseDesign::addName(); RoseDesign::findObject(); RoseDesign::nameTable()

rootObject()

RoseObject * rootObject();

void rootObject(
	RoseObject *val
	);

NOTE - This is deprecated and will be retired in a future ST-Developer release.

These functions get and set the root object of a design. A root object is not required but is a way of designating one object as the starting point for traversals. For example, an application may put an index in the root object slot and then use this index instead of the findObject() functions to quickly find the objects of interest to the application.

STEP Part 21 files do not support this information. You must save your design as a ROSE working form file in order to preserve this information.

The following example shows how an application can designate one object and then find the object again later.

/* Create a design and a picture object. */
RoseDesign * design = new RoseDesign (tutorial1);
Picture * pict = pnewIn(design) Picture;

design-> rootObject (pict);

Later on in the application, we can go back to the root object. Notice the use of the ROSE_CAST() macro to convert the pointer from RoseObject* to Picture*:

Picture * root = ROSE_CAST (Picture,design->rootObject());

save()

void save();

The save() function writes the design to disk in the file given by path(). The design is written using the file format specified with the format() function. By default, this will be the STEP Part 21 format, although other options are available.

The following example saves a design object in a number of different formats. Changing the format may also change the file extension.

RoseDesign * design;

design = new RoseDesign (gizmo);
design-> save();  /* write to gizmo.stp as P21 */

design-> format (step-zip);  /* */
design-> save();  /* write to gizmo.stp as zip-compressed P21 */

design-> format (standard);  /* save as binary rose file */
design-> save();  /* write to gizmo.rose as rose working format */

See Also

Reading and Writing Design Objects

saveAs()

void saveAs(
	const char * new_name
	);

The saveAs() function writes the design to disk using a different file name. This behaves like calling name() to change some or all of the path, calling save(), then setting the everything back to the original. This means the name can omit the directory or extension and the ones in the design will be used.

All filenames and paths are assumed to be UTF-8 encoded strings. The following example saves a design object under several different names.

// path = gizmo.stp
RoseDesign * d = new RoseDesign (gizmo);

// written as gizmo.stp
d-> save(); 

// written as foobar.stp
d-> saveAs(foobar);

// written as hello/foobar.stp
d-> saveAs(hello/foobar);

// written as hello/foobar.new
d-> saveAs(hello/foobar.new);

schemas()

ListOfRoseDesign * schemas();

void schemas(
	ListOfRoseDesign * schemas_objs
	);

The schemas() function returns the list of EXPRESS schemas for a design. Each schema is a RoseDesign that contains compiled EXPRESS definitions. This list determines which EXPRESS definitions are available to create instances with. The list may be empty or missing, so be sure to check for nulls.

This list of schemas is written to Part 21 files in the FILE_SCHEMA header section entity. The schemas() functions get and set this list. The useSchema() and addSchema() functions can also be used to modify this list.

The following example prints out the schemas for a design.

RoseDesign * design;
RoseDesign * schema;
ListOfRoseDesign * schemas;
unsigned i, sz;

schemas = design-> schemas();
for (i=0, sz=schemas-> size(); i<sz; i++) {
    printf (Design contains %s schema\n, 
	    schemas-> get(i)-> name());
}

See Also

EXPRESS Data Dictionary; ; RoseDesign::findDomain();

sections()

RoseDesignSection * sections();

Each design may contain several sections, one or more for the data objects, one for physical file header objects, and one for internal system objects. These sections correspond to the sections of a Part 21 physical file and are represented by instances of the RoseDesignSection class.

The sections() function returns a linked list of RoseDesignSection objects belonging to the design. The list can be traversed using the RoseDesignSection::next() function.

When a design is written as a ROSE working form file all three types of sections are preserved. STEP physical files only preserve the header and data sections. The system section, which contains name table and other information is not preserved.

See Also

Design Sections; RoseDesign::header_section(); RoseDesign::system_section()

setModified()

void setModified();

The setModified() function sets design to indicate that some changes have been made since it was last written to secondary storage. This function is used internally by update functions, and need not be called by application code.

RoseDesign * design;

printf (Design should be saved anyway\n);
design-> setModified();

See Also

RoseDesign::clrModified(); RoseDesign::isModified(); RoseInterface::saveWorkspace()

size()

unsigned size();

The size() function returns the number of data objects owned by the design. If the design has several data sections, this function returns the combined size of all data sections. This function does not count objects in the header, system, or reference sections. You can find the size of an individual section using RoseDesignSection::size().

RoseDesign * design;

printf (Design contains %d data objects\n, design-> size());
printf (Design contains %d header objects\n, 
	 design-> header_section()-> size());

system_section()

RoseDesignSection * system_section();

void system_section(
	RoseDesignSection * new_section
	);

The system_section() functions get and set the system section for a design. The system section contains support objects used by the ROSE library, such as the name table and other index objects. Objects in the system section are not written to STEP Part 21 files, but they are written to ROSE working form files.

The system_section() function never returns null. If the system section would be null, the function searches for the first section of type ROSE_SECTION_SYSTEM in the design. If the design does not have a section of that type, one will be created.

The system section can be traversed using a RoseCursor. The contents are already available through other functions such as nameTable()

RoseDesign * design;
RoseCursor objs;
RoseObject * obj;

objs.traverse (design-> system_section());
while ((obj = objs.next()) != 0) {
    /* do something with the system object */
}

See Also

Design Sections; RoseDesign::header_section(); RoseDesign::sections()

useSchema()

void useSchema(
	RoseDesign * schema
	);

void useSchema(
	const char * schema_name
	);

The useSchema() functions sets the design list of schemas to just one schema. The new schema replaces any other schemas previously in the list. Schemas determine which EXPRESS definitions are available to create instances. This list is written to Part 21 files in the FILE_SCHEMA header section entity. Two versions of the function are available. One version accepts a pointer to a schema design object, while the other accepts the name of the schema. If the schema is not in memory, it will be read in as with the RoseInterface::findDesign() function.

The following examples create a design and give it one schema with the useSchema() function. This is equivalent to supplying the schema through the design constructor.

RoseDesign * design;

design = new RoseDesign (gizmo);
design-> useSchema (config_control_design);  /* add AP203 schema */

/* equivalent code */
design = new RoseDesign (gizmo,config_control_design);

The following example does the same thing, but uses findDesign() to find the schema first:

RoseDesign * design;
RoseDesign * cc_schema;

design = new RoseDesign (gizmo);
cc_schema = ROSE.findDesign (config_control_design);*/

design-> useSchema (cc_schema);      /* add AP203 schema */

See Also

EXPRESS Data Dictionary; RoseDesign::addSchema(); RoseDesign::findDomain(); RoseDesign::schemas()