(* $Id: topology_schema.exp,v 1.36 2021/05/06 16:23:00 kevin Exp $ ISO 10303 TC184/SC4/WG12 N10586 EXPRESS Source: ISO 10303-42 ed7 Geometric and topological representation - Topology schema The following permission notice and disclaimer shall be included in all copies of this EXPRESS schema ("the Schema"), and derivations of the Schema: Copyright ISO 2021 All rights reserved Permission is hereby granted, free of charge in perpetuity, to any person obtaining a copy of the Schema, to use, copy, modify, merge and distribute free of charge, copies of the Schema for the purposes of developing, implementing, installing and using software based on the Schema, and to permit persons to whom the Schema is furnished to do so, subject to the following conditions: THE SCHEMA IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SCHEMA OR THE USE OR OTHER DEALINGS IN THE SCHEMA. In addition, any modified copy of the Schema shall include the following notice: THIS SCHEMA HAS BEEN MODIFIED FROM THE SCHEMA DEFINED IN ISO 10303-42 ed7 Geometric and topological representation - Topology schema AND SHOULD NOT BE INTERPRETED AS COMPLYING WITH THAT STANDARD *) SCHEMA topology_schema '{iso standard 10303 part(42) version(11) object(1) topology_schema(2)}'; REFERENCE FROM basic_attribute_schema (aggregate_id_attribute, -- ISO 10303-41 get_aggregate_id_value, get_id_value, id_attribute, id_attribute_select); REFERENCE FROM geometry_schema; -- ISO 10303-42 REFERENCE FROM representation_schema(representation, representation_item); -- ISO 10303-43 REFERENCE FROM support_resource_schema (bag_to_set, identifier); -- ISO 10303-41 CONSTANT dummy_tri : topological_representation_item := representation_item('')|| topological_representation_item(); END_CONSTANT; TYPE list_of_reversible_topology_item = LIST [0:?] of reversible_topology_item; END_TYPE; TYPE reversible_topology = SELECT (reversible_topology_item, list_of_reversible_topology_item, set_of_reversible_topology_item); END_TYPE; TYPE reversible_topology_item = SELECT (edge, path, face, face_bound, closed_shell, open_shell); END_TYPE; TYPE set_of_reversible_topology_item = SET [0:?] of reversible_topology_item; END_TYPE; TYPE tri_id_attribute_select = SELECT BASED_ON id_attribute_select WITH ( topological_representation_item); END_TYPE; TYPE shell = SELECT (vertex_shell, wire_shell, open_shell, closed_shell); END_TYPE; ENTITY closed_shell SUBTYPE OF (connected_face_set); END_ENTITY; ENTITY connected_edge_set SUBTYPE OF (topological_representation_item); ces_edges : SET [1:?] OF edge; END_ENTITY; ENTITY connected_edge_sub_set SUBTYPE OF (connected_edge_set); parent_edge_set : connected_edge_set; WHERE WR1: SELF :<>: parent_edge_set; END_ENTITY; ENTITY connected_face_set SUPERTYPE OF (ONEOF (closed_shell, open_shell)) SUBTYPE OF (topological_representation_item); cfs_faces : SET [1:?] OF face; END_ENTITY; ENTITY connected_face_sub_set SUBTYPE OF (connected_face_set); parent_face_set : connected_face_set; WHERE WR1: SELF :<>: parent_face_set; END_ENTITY; ENTITY connected_volume_set SUBTYPE OF(topological_representation_item); cvs_volumes : SET [1:?] OF volume_with_faces; END_ENTITY; ENTITY connected_volume_sub_set SUBTYPE OF(connected_volume_set); parent_volume_set : connected_volume_set; WHERE WR1: SELF :<>: parent_volume_set; END_ENTITY; ENTITY edge SUPERTYPE OF(ONEOF(edge_curve, oriented_edge, subedge)) SUBTYPE OF (topological_representation_item); edge_start : vertex; edge_end : vertex; END_ENTITY; ENTITY subedge SUBTYPE OF (edge); parent_edge : edge; WHERE WR1: SELF :<>: parent_edge; END_ENTITY; ENTITY edge_curve SUBTYPE OF(edge,geometric_representation_item); edge_geometry : curve; same_sense : BOOLEAN; END_ENTITY; ENTITY edge_loop SUBTYPE OF (loop,path); DERIVE ne : INTEGER := SIZEOF(SELF\path.edge_list); WHERE WR1: (SELF\path.edge_list[1].edge_start) :=: (SELF\path.edge_list[ne].edge_end); END_ENTITY; ENTITY face SUPERTYPE OF(ONEOF(face_surface, subface, oriented_face)) SUBTYPE OF (topological_representation_item); bounds : SET[1:?] OF face_bound; WHERE WR1: NOT (mixed_loop_type_set(list_to_set(list_face_loops(SELF)))); WR2: SIZEOF(QUERY(temp <* bounds | 'TOPOLOGY_SCHEMA.FACE_OUTER_BOUND' IN TYPEOF(temp))) <= 1; END_ENTITY; ENTITY subface SUBTYPE OF (face); parent_face : face; WHERE WR1: NOT (mixed_loop_type_set(list_to_set(list_face_loops(SELF)) + list_to_set(list_face_loops(parent_face)))); WR2: SELF :<>: parent_face; END_ENTITY; ENTITY face_bound SUBTYPE OF(topological_representation_item); bound : loop; orientation : BOOLEAN; END_ENTITY; ENTITY face_outer_bound SUBTYPE OF (face_bound); END_ENTITY; ENTITY face_surface SUBTYPE OF(face,geometric_representation_item); face_geometry : surface; same_sense : BOOLEAN; WHERE WR1: NOT ('GEOMETRY_SCHEMA.ORIENTED_SURFACE' IN TYPEOF(face_geometry)); END_ENTITY; ENTITY loop SUPERTYPE OF (ONEOF(vertex_loop, edge_loop, poly_loop)) SUBTYPE OF (topological_representation_item); END_ENTITY; ENTITY open_path SUBTYPE OF (path); DERIVE ne : INTEGER := SIZEOF(SELF\path.edge_list); WHERE WR1: (SELF\path.edge_list[1].edge_element.edge_start) :<>: (SELF\path.edge_list[ne].edge_element.edge_end); END_ENTITY; ENTITY open_shell SUBTYPE OF (connected_face_set); END_ENTITY; ENTITY oriented_closed_shell SUBTYPE OF (closed_shell); closed_shell_element : closed_shell; orientation : BOOLEAN; DERIVE SELF\connected_face_set.cfs_faces : SET [1:?] OF face := conditional_reverse(SELF.orientation, SELF.closed_shell_element.cfs_faces); WHERE WR1: NOT ('TOPOLOGY_SCHEMA.ORIENTED_CLOSED_SHELL' IN TYPEOF (SELF.closed_shell_element)); END_ENTITY; ENTITY oriented_edge SUBTYPE OF (edge); edge_element : edge; orientation : BOOLEAN; DERIVE SELF\edge.edge_start : vertex := boolean_choose (SELF.orientation, SELF.edge_element.edge_start, SELF.edge_element.edge_end); SELF\edge.edge_end : vertex := boolean_choose (SELF.orientation, SELF.edge_element.edge_end, SELF.edge_element.edge_start); WHERE WR1: NOT ('TOPOLOGY_SCHEMA.ORIENTED_EDGE' IN TYPEOF (SELF.edge_element)); END_ENTITY; ENTITY oriented_face SUBTYPE OF (face); face_element : face; orientation : BOOLEAN; DERIVE SELF\face.bounds : SET[1:?] OF face_bound := conditional_reverse(SELF.orientation,SELF.face_element.bounds); WHERE WR1: NOT ('TOPOLOGY_SCHEMA.ORIENTED_FACE' IN TYPEOF (SELF.face_element)); END_ENTITY; ENTITY oriented_open_shell SUBTYPE OF (open_shell); open_shell_element : open_shell; orientation : BOOLEAN; DERIVE SELF\connected_face_set.cfs_faces : SET [1:?] OF face := conditional_reverse(SELF.orientation, SELF.open_shell_element.cfs_faces); WHERE WR1: NOT ('TOPOLOGY_SCHEMA.ORIENTED_OPEN_SHELL' IN TYPEOF (SELF.open_shell_element)); END_ENTITY; ENTITY oriented_path SUBTYPE OF (path); path_element : path; orientation : BOOLEAN; DERIVE SELF\path.edge_list : LIST [1:?] OF UNIQUE oriented_edge := conditional_reverse(SELF.orientation, SELF.path_element.edge_list); WHERE WR1: NOT ('TOPOLOGY_SCHEMA.ORIENTED_PATH' IN TYPEOF (SELF.path_element)); END_ENTITY; ENTITY path SUPERTYPE OF (ONEOF(open_path, edge_loop, oriented_path)) SUBTYPE OF (topological_representation_item); edge_list : LIST [1:?] OF UNIQUE oriented_edge; WHERE WR1: path_head_to_tail(SELF); END_ENTITY; ENTITY subpath SUBTYPE OF (path); parent_path : path; WHERE WR1: SELF :<>: parent_path; WR2: NOT (('TOPOLOGY_SCHEMA.EDGE_LOOP' IN TYPEOF(SELF)) AND ('TOPOLOGY_SCHEMA.OPEN_PATH' IN TYPEOF(parent_path))); END_ENTITY; --IP1: The domain of the subpath shall be within the domain of the parent_path. --IP2: If the subpath is an edge_loop, the domain of the subpath shall be the same as the parent_path. --IP3: If the subpath is an edge_loop and the parent_path is an oriented_path, the oriented_path shall be closed to form a loop. ENTITY poly_loop SUBTYPE OF (loop,geometric_representation_item); polygon : LIST [3:?] OF UNIQUE cartesian_point; END_ENTITY; ENTITY seam_edge SUBTYPE OF (oriented_edge); pcurve_reference : pcurve ; WHERE WR1 : ( 'TOPOLOGY_SCHEMA.EDGE_CURVE' IN TYPEOF (edge_element) ) AND ('TOPOLOGY_SCHEMA.SEAM_CURVE' IN TYPEOF (edge_element\edge_curve.edge_geometry)) ; WR2 : pcurve_reference IN edge_element\edge_curve.edge_geometry\ surface_curve.associated_geometry ; END_ENTITY; ENTITY topological_representation_item SUPERTYPE OF (ONEOF(vertex, edge, face_bound, face, vertex_shell, wire_shell, connected_edge_set, connected_face_set, connected_volume_set, volume_with_faces, (loop ANDOR path))) SUBTYPE OF (representation_item); DERIVE permanent_id : identifier := get_id_value(SELF); permanent_aggregate_id : identifier := get_aggregate_id_value(SELF); WHERE WR1: SIZEOF(USEDIN(SELF,'BASIC_ATTRIBUTE_SCHEMA.ID_ATTRIBUTE.IDENTIFIED_ITEM')) <= 1; WR2: SIZEOF(USEDIN(SELF,'BASIC_ATTRIBUTE_SCHEMA.AGGREGATE_ID_ATTRIBUTE.IDENTIFIED_ITEM')) <= 1; END_ENTITY; ENTITY vertex SUBTYPE OF (topological_representation_item); END_ENTITY; ENTITY vertex_point SUBTYPE OF(vertex,geometric_representation_item); vertex_geometry : point; END_ENTITY; ENTITY vertex_loop SUBTYPE OF (loop); loop_vertex : vertex; END_ENTITY; ENTITY volume_with_faces ABSTRACT SUPERTYPE OF (ONEOF(volume_with_shell, volume_with_parametric_boundary)) SUBTYPE OF(geometric_representation_item, topological_representation_item); volume_geometry : volume; END_ENTITY; ENTITY volume_with_parametric_boundary SUBTYPE OF(volume_with_faces); outer_bound : LIST [6:6] OF face; END_ENTITY; ENTITY volume_with_shell SUBTYPE OF(volume_with_faces); outer_bound : closed_shell; END_ENTITY; ENTITY vertex_shell SUBTYPE OF (topological_representation_item); vertex_shell_extent : vertex_loop; END_ENTITY; ENTITY wire_shell SUBTYPE OF (topological_representation_item); wire_shell_extent : SET [1:?] OF loop; WHERE WR1: NOT mixed_loop_type_set(wire_shell_extent); END_ENTITY; FUNCTION boolean_choose (b : boolean; choice1, choice2 : generic : item) : generic : item; IF b THEN RETURN (choice1); ELSE RETURN (choice2); END_IF; END_FUNCTION; FUNCTION closed_shell_reversed (a_shell : closed_shell) : oriented_closed_shell; LOCAL the_reverse : oriented_closed_shell; END_LOCAL; IF ('TOPOLOGY_SCHEMA.ORIENTED_CLOSED_SHELL' IN TYPEOF (a_shell) ) THEN the_reverse := dummy_tri || connected_face_set ( a_shell\connected_face_set.cfs_faces) || closed_shell () || oriented_closed_shell( a_shell\oriented_closed_shell.closed_shell_element, NOT(a_shell\oriented_closed_shell.orientation)); ELSE the_reverse := dummy_tri || connected_face_set ( a_shell\connected_face_set.cfs_faces) || closed_shell () || oriented_closed_shell (a_shell, FALSE); END_IF; RETURN (the_reverse); END_FUNCTION; FUNCTION conditional_reverse (p : BOOLEAN; an_item : reversible_topology) : reversible_topology; IF p THEN RETURN (an_item); ELSE RETURN (topology_reversed (an_item)); END_IF; END_FUNCTION; FUNCTION edge_curve_pcurves (an_edge : edge_curve; the_surface_curves : SET OF surface_curve) : SET OF pcurve; LOCAL a_curve : curve; result : SET OF pcurve; the_geometry : LIST[1:2] OF pcurve_or_surface; END_LOCAL; a_curve := an_edge.edge_geometry; result := []; IF 'GEOMETRY_SCHEMA.PCURVE' IN TYPEOF(a_curve) THEN result := result + a_curve; ELSE IF 'GEOMETRY_SCHEMA.SURFACE_CURVE' IN TYPEOF(a_curve) THEN the_geometry := a_curve\surface_curve.associated_geometry; REPEAT k := 1 TO SIZEOF(the_geometry); IF 'GEOMETRY_SCHEMA.PCURVE' IN TYPEOF (the_geometry[k]) THEN result := result + the_geometry[k]; END_IF; END_REPEAT; ELSE REPEAT j := 1 TO SIZEOF(the_surface_curves); the_geometry := the_surface_curves[j].associated_geometry; IF the_surface_curves[j].curve_3d :=: a_curve THEN REPEAT k := 1 TO SIZEOF(the_geometry); IF 'GEOMETRY_SCHEMA.PCURVE' IN TYPEOF (the_geometry[k]) THEN result := result + the_geometry[k]; END_IF; END_REPEAT; END_IF; END_REPEAT; END_IF; END_IF; RETURN (result); END_FUNCTION; FUNCTION edge_reversed (an_edge : edge) : oriented_edge; LOCAL the_reverse : oriented_edge; END_LOCAL; IF ('TOPOLOGY_SCHEMA.ORIENTED_EDGE' IN TYPEOF (an_edge) ) THEN the_reverse := dummy_tri || edge(an_edge.edge_end, an_edge.edge_start) || oriented_edge(an_edge\oriented_edge.edge_element, NOT (an_edge\oriented_edge.orientation)) ; ELSE the_reverse := dummy_tri || edge(an_edge.edge_end, an_edge.edge_start) || oriented_edge(an_edge, FALSE); END_IF; RETURN (the_reverse); END_FUNCTION; FUNCTION face_bound_reversed (a_face_bound : face_bound) : face_bound; LOCAL the_reverse : face_bound ; END_LOCAL; IF ('TOPOLOGY_SCHEMA.FACE_OUTER_BOUND' IN TYPEOF (a_face_bound) ) THEN the_reverse := dummy_tri || face_bound(a_face_bound\face_bound.bound, NOT (a_face_bound\face_bound.orientation)) || face_outer_bound() ; ELSE the_reverse := dummy_tri || face_bound(a_face_bound.bound, NOT(a_face_bound.orientation)); END_IF; RETURN (the_reverse); END_FUNCTION; FUNCTION face_reversed (a_face : face) : oriented_face; LOCAL the_reverse : oriented_face ; END_LOCAL; IF ('TOPOLOGY_SCHEMA.ORIENTED_FACE' IN TYPEOF (a_face) ) THEN the_reverse := dummy_tri || face(set_of_topology_reversed(a_face.bounds)) || oriented_face(a_face\oriented_face.face_element, NOT (a_face\oriented_face.orientation)) ; ELSE the_reverse := dummy_tri || face(set_of_topology_reversed(a_face.bounds)) || oriented_face(a_face, FALSE) ; END_IF; RETURN (the_reverse); END_FUNCTION; --new FUNCTION get_tri_in_representations (members : SET OF representation) : SET OF topological_representation_item; LOCAL tri_set : SET OF topological_representation_item := []; END_LOCAL; IF SIZEOF(members) = 0 THEN RETURN(?); END_IF; REPEAT i := LOINDEX(members) TO HIINDEX(members); REPEAT J := LOINDEX(members[i]\representation.items) TO HIINDEX(members[i]\representation.items); IF 'TOPOLOGY_SCHEMA.TOPOLOGICAL_REPRESENTATION_ITEM' IN TYPEOF(members[i]\representation.items[j]) THEN tri_set := tri_set + members[i]\representation.items[j]; END_IF; END_REPEAT; END_REPEAT; RETURN(tri_set); END_FUNCTION; FUNCTION list_face_loops(f: face) : LIST[0:?] OF loop; LOCAL loops : LIST[0:?] OF loop := []; END_LOCAL; REPEAT i := 1 TO SIZEOF(f.bounds); loops := loops +(f.bounds[i].bound); END_REPEAT; RETURN(loops); END_FUNCTION; FUNCTION list_loop_edges(l: loop): LIST[0:?] OF edge; LOCAL edges : LIST[0:?] OF edge := []; END_LOCAL; IF 'TOPOLOGY_SCHEMA.EDGE_LOOP' IN TYPEOF(l) THEN REPEAT i := 1 TO SIZEOF(l\path.edge_list); edges := edges + (l\path.edge_list[i].edge_element); END_REPEAT; END_IF; RETURN(edges); END_FUNCTION; FUNCTION list_of_topology_reversed (a_list : list_of_reversible_topology_item) : list_of_reversible_topology_item; LOCAL the_reverse : list_of_reversible_topology_item; END_LOCAL; the_reverse := []; REPEAT i := 1 TO SIZEOF (a_list); the_reverse := topology_reversed (a_list [i]) + the_reverse; END_REPEAT; RETURN (the_reverse); END_FUNCTION; FUNCTION list_shell_edges(s : shell) : LIST[0:?] OF edge; LOCAL edges : LIST[0:?] OF edge := []; END_LOCAL; REPEAT i := 1 TO SIZEOF(list_shell_loops(s)); edges := edges + list_loop_edges(list_shell_loops(s)[i]); END_REPEAT; RETURN(edges); END_FUNCTION; FUNCTION list_shell_faces(s : shell) : LIST[0:?] OF face; LOCAL faces : LIST[0:?] OF face := []; END_LOCAL; IF ('TOPOLOGY_SCHEMA.CLOSED_SHELL' IN TYPEOF(s)) OR ('TOPOLOGY_SCHEMA.OPEN_SHELL' IN TYPEOF(s)) THEN REPEAT i := 1 TO SIZEOF(s\connected_face_set.cfs_faces); faces := faces + s\connected_face_set.cfs_faces[i]; END_REPEAT; END_IF; RETURN(faces); END_FUNCTION; FUNCTION list_shell_loops(s : shell) : LIST[0:?] OF loop; LOCAL loops : LIST[0:?] OF loop := []; END_LOCAL; IF 'TOPOLOGY_SCHEMA.VERTEX_SHELL' IN TYPEOF(s) THEN loops := loops + s.vertex_shell_extent; END_IF; IF 'TOPOLOGY_SCHEMA.WIRE_SHELL' IN TYPEOF(s) THEN REPEAT i := 1 TO SIZEOF(s.wire_shell_extent); loops := loops + s.wire_shell_extent[i]; END_REPEAT; END_IF; IF ('TOPOLOGY_SCHEMA.OPEN_SHELL' IN TYPEOF(s)) OR ('TOPOLOGY_SCHEMA.CLOSED_SHELL' IN TYPEOF(s)) THEN REPEAT i := 1 TO SIZEOF(s.cfs_faces); loops := loops + list_face_loops(s.cfs_faces[i]); END_REPEAT; END_IF; RETURN(loops); END_FUNCTION; FUNCTION list_to_set(l : LIST [0:?] OF GENERIC:T) : SET OF GENERIC:T; LOCAL s : SET OF GENERIC:T := []; END_LOCAL; REPEAT i := 1 TO SIZEOF(l); s := s + l[i]; END_REPEAT; RETURN(s); END_FUNCTION; FUNCTION mixed_loop_type_set(l: SET[0:?] OF loop): LOGICAL; LOCAL poly_loop_type: LOGICAL; END_LOCAL; IF(SIZEOF(l) <= 1) THEN RETURN(FALSE); END_IF; poly_loop_type := ('TOPOLOGY_SCHEMA.POLY_LOOP' IN TYPEOF(l[1])); REPEAT i := 2 TO SIZEOF(l); IF(('TOPOLOGY_SCHEMA.POLY_LOOP' IN TYPEOF(l[i])) <> poly_loop_type) THEN RETURN(TRUE); END_IF; END_REPEAT; RETURN(FALSE); END_FUNCTION; FUNCTION open_shell_reversed ( a_shell : open_shell) : oriented_open_shell; LOCAL the_reverse : oriented_open_shell; END_LOCAL; IF ('TOPOLOGY_SCHEMA.ORIENTED_OPEN_SHELL' IN TYPEOF (a_shell) ) THEN the_reverse := dummy_tri || connected_face_set ( a_shell\connected_face_set.cfs_faces) || open_shell () || oriented_open_shell( a_shell\oriented_open_shell.open_shell_element, (NOT (a_shell\oriented_open_shell.orientation))); ELSE the_reverse := dummy_tri || connected_face_set ( a_shell\connected_face_set.cfs_faces) || open_shell () || oriented_open_shell (a_shell, FALSE); END_IF; RETURN (the_reverse); END_FUNCTION; FUNCTION path_head_to_tail(a_path : path) : LOGICAL; LOCAL n : INTEGER; p : LOGICAL := TRUE; END_LOCAL; n := SIZEOF (a_path.edge_list); REPEAT i := 2 TO n; p := p AND (a_path.edge_list[i-1].edge_end :=: a_path.edge_list[i].edge_start); END_REPEAT; RETURN (p); END_FUNCTION; FUNCTION path_reversed (a_path : path) : oriented_path; LOCAL the_reverse : oriented_path ; END_LOCAL; IF ('TOPOLOGY_SCHEMA.ORIENTED_PATH' IN TYPEOF (a_path) ) THEN the_reverse := dummy_tri || path(list_of_topology_reversed (a_path.edge_list)) || oriented_path(a_path\oriented_path.path_element, NOT(a_path\oriented_path.orientation)) ; ELSE the_reverse := dummy_tri || path(list_of_topology_reversed (a_path.edge_list)) || oriented_path(a_path, FALSE); END_IF; RETURN (the_reverse); END_FUNCTION; FUNCTION set_of_topology_reversed (a_set : set_of_reversible_topology_item) : set_of_reversible_topology_item; LOCAL the_reverse : set_of_reversible_topology_item; END_LOCAL; the_reverse := []; REPEAT i := 1 TO SIZEOF (a_set); the_reverse := the_reverse + topology_reversed (a_set [i]); END_REPEAT; RETURN (the_reverse); END_FUNCTION; FUNCTION shell_reversed (a_shell : shell) : shell; IF ('TOPOLOGY_SCHEMA.OPEN_SHELL' IN TYPEOF (a_shell) ) THEN RETURN (open_shell_reversed (a_shell)); ELSE IF ('TOPOLOGY_SCHEMA.CLOSED_SHELL' IN TYPEOF (a_shell) ) THEN RETURN (closed_shell_reversed (a_shell)); ELSE RETURN (?); END_IF; END_IF; END_FUNCTION; FUNCTION topology_reversed (an_item : reversible_topology) : reversible_topology; IF ('TOPOLOGY_SCHEMA.EDGE' IN TYPEOF (an_item)) THEN RETURN (edge_reversed (an_item)); END_IF; IF ('TOPOLOGY_SCHEMA.PATH' IN TYPEOF (an_item)) THEN RETURN (path_reversed (an_item)); END_IF; IF ('TOPOLOGY_SCHEMA.FACE_BOUND' IN TYPEOF (an_item)) THEN RETURN (face_bound_reversed (an_item)); END_IF; IF ('TOPOLOGY_SCHEMA.FACE' IN TYPEOF (an_item)) THEN RETURN (face_reversed (an_item)); END_IF; IF ('TOPOLOGY_SCHEMA.SHELL' IN TYPEOF (an_item)) THEN RETURN (shell_reversed (an_item)); END_IF; IF ('SET' IN TYPEOF (an_item)) THEN RETURN (set_of_topology_reversed (an_item)); END_IF; IF ('LIST' IN TYPEOF (an_item)) THEN RETURN (list_of_topology_reversed (an_item)); END_IF; RETURN (?); END_FUNCTION; (* The FUNCTION valid_tri_ids returns TRUE if each tri has an id and if each id is used only once in the SET of tri. Note: The value of aggregate_id and of id shall be disjoint in order to support possible use case where there shall be no more than one id of any kind assigned to a tri. *) FUNCTION valid_tri_ids (objs : SET OF topological_representation_item) : BOOLEAN; LOCAL values : BAG OF identifier := []; END_LOCAL; REPEAT i := LOINDEX(objs) TO HIINDEX(objs); --each tri shall have at least one id. IF NOT(EXISTS(objs[i]\topological_representation_item.permanent_id) OR EXISTS(objs[i]\topological_representation_item.permanent_aggregate_id)) THEN RETURN(FALSE); END_IF; values := values + objs[i]\topological_representation_item.permanent_id + objs[i]\topological_representation_item.permanent_aggregate_id; END_REPEAT; --ids are unique across both types IF SIZEOF(bag_to_set(values)) <> SIZEOF(values) THEN RETURN(FALSE); END_IF; RETURN (TRUE); END_FUNCTION; FUNCTION vertex_point_pcurves (a_vertex : vertex_point; the_degenerates : SET OF evaluated_degenerate_pcurve) : SET OF degenerate_pcurve; LOCAL a_point : point; result : SET OF degenerate_pcurve; END_LOCAL; a_point := a_vertex.vertex_geometry; result := []; IF 'GEOMETRY_SCHEMA.DEGENERATE_PCURVE' IN TYPEOF(a_point) THEN result := result + a_point; ELSE REPEAT j := 1 TO SIZEOF(the_degenerates); IF (the_degenerates[j].equivalent_point :=: a_point) THEN result := result + the_degenerates[j]; END_IF; END_REPEAT; END_IF; RETURN (result); END_FUNCTION; END_SCHEMA; -- end TOPOLOGY schema