Skip to content

Commit 49becf5

Browse files
authored
Merge pull request #355 from Systems-Modeling/ST6RI-532
ST6RI-532 Minor fixes to space modeling & shape library
2 parents 47e6b8b + ebdc9b1 commit 49becf5

4 files changed

Lines changed: 95 additions & 67 deletions

File tree

sysml.library/Domain Libraries/Geometry/ShapeItems.sysml

Lines changed: 57 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,35 @@ package ShapeItems {
99
private import Objects::*;
1010
private import Items::Item;
1111
private import SequenceFunctions::isEmpty;
12-
12+
private import SequenceFunctions::notEmpty;
13+
private import SequenceFunctions::size;
14+
private import ControlFunctions::'?';
15+
1316
/**
14-
* A Line is a Curve that is a straight line of a given length.
17+
* A PlanarCurve is a Curve with a given length embeddable in a plane.
1518
*/
16-
item def Line :> Curve {
17-
attribute :>> length;
18-
attribute :>> outerSpaceDimension = 1;
19+
item def PlanarCurve :> Curve {
20+
attribute :>> length [1] ;
21+
22+
constraint { notEmpty(outerSpaceDimension) & outerSpaceDimension <= 2 }
1923
}
2024

2125
/**
2226
* A PlanarSurface is a flat Surface with a given area.
2327
*/
2428
item def PlanarSurface :> Surface {
25-
attribute :>> area;
29+
attribute :>> area [1];
2630
attribute :>> outerSpaceDimension = 2;
31+
32+
item :>> shape : PlanarCurve;
33+
}
34+
35+
/**
36+
* A Line is a Curve that is a straight line of a given length.
37+
*/
38+
item def Line :> PlanarCurve {
39+
attribute :>> length [1];
40+
attribute :>> outerSpaceDimension = 1;
2741
}
2842

2943
/**
@@ -39,12 +53,12 @@ package ShapeItems {
3953
/**
4054
* A Circle is a Path in the shape of a circle of a given radius.
4155
*/
42-
item def Circle :> Path {
43-
attribute radius :>> radius;
56+
item def Circle :> Path, PlanarCurve {
57+
attribute :>> radius;
4458

4559
item :>> faces [0];
4660
item :>> edges [1] {
47-
attribute circumference :>> length = Circle::radius * TrigFunctions::pi;
61+
attribute circumference :>> length = Circle::radius * TrigFunctions::pi * 2;
4862
item :>> shape : Item [0];
4963
item :>> vertices [0];
5064
}
@@ -54,15 +68,15 @@ package ShapeItems {
5468
/**
5569
* A Disc is a Shell bounded by a Circle.
5670
*/
57-
item def Disc :> Shell {
58-
attribute radius :>> radius;
71+
item def Disc :> Shell, PlanarSurface {
72+
attribute :>> radius;
5973

6074
item :>> shape : Circle [1] {
6175
attribute :>> radius = Disc::radius;
6276
}
6377

6478
item :>> faces : PlanarSurface [1] {
65-
item :>> edges [1];
79+
item :>> edges [1];
6680
}
6781
item :>> edges : Circle [1] = shape;
6882
item :>> vertices [0];
@@ -76,38 +90,42 @@ package ShapeItems {
7690
item def Sphere :> Shell {
7791
attribute :>> radius;
7892

79-
item faces : Surface [1] :>> faces;
93+
item :>> faces [1];
8094
item :>> edges [0];
8195
item :>> vertices [0];
96+
97+
attribute :>> genus = 0;
8298
}
8399

84100
/**
85101
* A Cone is a Shell in the shape of a right circular code, possibly truncated, with given
86102
* baseRadius, apexRadius and height.
87103
*/
88104
item def Cone :> Shell {
89-
attribute baseRadius :> radius;
90-
attribute apexRadius :> radius default 0 [m];
91-
attribute :>> height;
105+
attribute baseRadius [1] = radius;
106+
attribute apexRadius [1] default 0 [m];
107+
attribute :>> height [1];
108+
109+
attribute :>> radius [1];
92110
attribute isTruncated : Boolean [1] = (apexRadius > 0);
93111

94-
item faces : Surface [2..3] :>> faces;
112+
item :>> faces [2..3];
95113
item bf : Disc [1] :> faces;
96114
item af : Disc [0..1] :> faces;
97115
item cf : Surface [1] :> faces;
98116
constraint { (apexRadius == 0) == isEmpty(af) }
99117

100-
item edges : Circle [1..2] :>> edges;
101-
item be [1] :> edges {
118+
item :>> edges : Circle [2..4];
119+
item be [2] :> edges {
102120
attribute :>> radius = baseRadius;
103121
}
104-
item ae [0..1] :> edges {
122+
item ae [0..2] :> edges {
105123
attribute :>> radius = apexRadius;
106124
}
107-
constraint { isEmpty(af) == isEmpty(ae) }
125+
constraint { isEmpty(af) ? isEmpty(ae) : size(ae) == 2 }
108126

109-
item vertices : Point [0..1] :>> vertices;
110-
constraint { isEmpty(ae) == isEmpty(vertices) }
127+
item :>> vertices [0..1];
128+
constraint { isEmpty(ae) == notEmpty(vertices) }
111129

112130
/* Faces to edges */
113131
connection :WithinBoth connect bf.edges [1] to be [0..*];
@@ -122,38 +140,37 @@ package ShapeItems {
122140
connection :WithinBoth connect be [2] to be [2];
123141
connection :WithinBoth connect ae [2] to ae [2];
124142

143+
attribute :>> genus = 0;
125144
}
126145

127146
/**
128147
* A Cylinder is a Cone whose baseRadius and apexRadius are the same, representing
129148
* a right circular cylinder.
130149
*/
131150
item def Cylinder :> Cone {
132-
attribute :>> radius = baseRadius;
133-
134-
attribute :>> baseRadius = apexRadius;
151+
attribute :>> apexRadius = baseRadius;
135152
}
136153

137154
/**
138155
* A Cuboid is a Shell in the shape of a six-sided polyhedron with rectangular sides, with
139156
* given length, width and height.
140157
*/
141158
item def Cuboid :> Shell {
142-
attribute :>> length;
143-
attribute :>> width;
144-
attribute :>> height;
159+
attribute :>> length [1];
160+
attribute :>> width [1];
161+
attribute :>> height [1];
145162

146163
item faces : PlanarSurface [6] :>> faces {
147164
item :>> edges [4];
148165
}
149-
item tf :> faces [1];
150-
item bf :> faces [1];
151-
item ff :> faces [1];
152-
item rf :> faces [1];
153-
item slf :> faces [1];
154-
item srf :> faces [1];
155-
156-
item edges : Line [12] :>> edges {
166+
item tf [1] :> faces;
167+
item bf [1] :> faces;
168+
item ff [1] :> faces;
169+
item rf [1] :> faces;
170+
item slf [1] :> faces;
171+
item srf [1] :> faces;
172+
173+
item :>> edges : Line [24] {
157174
item :>> vertices [2];
158175
}
159176
item tfe [2] :> edges { attribute :>> length = Cuboid::length; }
@@ -169,7 +186,7 @@ package ShapeItems {
169186
item urle [2] :> edges { attribute :>> length = Cuboid::height; }
170187
item urre [2] :> edges { attribute :>> length = Cuboid::height; }
171188

172-
item vertices : Point [8] :>> vertices;
189+
item :>> vertices [24];
173190
item tflv [3] :> vertices;
174191
item tfrv [3] :> vertices;
175192
item trlv [3] :> vertices;
@@ -261,6 +278,8 @@ package ShapeItems {
261278
connection :WithinBoth connect bfrv [3] to bfrv [3];
262279
connection :WithinBoth connect brlv [3] to brlv [3];
263280
connection :WithinBoth connect brrv [3] to brrv [3];
281+
282+
attribute :>> genus = 0;
264283
}
265284
alias Box for Cuboid;
266285
}

sysml.library/Kernel Library/Objects.kerml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ package Objects {
1616
private import SequenceFunctions::notEmpty;
1717
private import SequenceFunctions::union;
1818
private import CollectionFunctions::contains;
19-
private import ScalarValues::Integer;
19+
private import ScalarValues::Integer;
20+
private import ScalarValues::Natural;
2021

2122
/**
2223
* Object is the most general class of structural occurrences that may change over time.
@@ -81,9 +82,9 @@ package Objects {
8182
struct all Surface specializes Object {
8283
feature redefines innerSpaceDimension = 2;
8384
/* The number of "holes" in this Surface, assuming it isClosed. */
84-
feature genus : Integer[0..1] default 0;
85+
feature genus : Natural[0..1] default 0;
8586

86-
inv { notEmpty(genus) implies (isClosed & genus >= 0) }
87+
inv { notEmpty(genus) implies isClosed }
8788
}
8889

8990
/*

sysml.library/Kernel Library/Occurrences.kerml

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ package Occurrences {
3737
feature predecessors: Occurrence[0..*] subsets occurrences;
3838

3939
/**
40-
* Occurrences that start after this occcurrence ends.
40+
* Occurrences that start after this occurrence ends.
4141
*/
4242
feature successors: Occurrence[0..*] subsets occurrences;
4343

@@ -84,7 +84,8 @@ package Occurrences {
8484
* to 3, without regard to higher dimensional spaces it might be emedded in.
8585
*/
8686
feature innerSpaceDimension : Natural [1];
87-
inv { innerSpaceDimension >= 0 & innerSpaceDimension <= 3 }
87+
88+
inv { innerSpaceDimension <= 3 }
8889

8990
/**
9091
* For occurrences of innerSpaceDimension 1 or 2, the number of variables need to
@@ -188,7 +189,7 @@ package Occurrences {
188189
/**
189190
* Occurrences of which this occurrence is a space shot.
190191
*/
191-
feature spaceShotOf: Occurrence[1..*] subsets spaceSliceOf;
192+
feature spaceShotOf: Occurrence[0..*] subsets spaceSliceOf;
192193

193194
/**
194195
* Sets of occurrences, where the time and space taken by all the occurrences in each
@@ -270,12 +271,12 @@ package Occurrences {
270271
* An Occurrence of which this one is the space interior.
271272
*/
272273
feature spaceInteriorOf: Occurrence[0..1] subsets spaceSliceOf;
274+
273275
inv { notEmpty(spaceInterior) implies spaceInterior.innerSpaceDimension == innerSpaceDimension }
274-
inv { innerSpaceDimension == 0 implies isEmpty(spaceInterior) }
275276

276277
/**
277-
* A space shot of this Occurrence that is not among those of its space interior, of
278-
* which it must be outside. It must have no spaceBoundary.
278+
* A space shot of this Occurrence that is not among those of its space interior,
279+
* which must be outside it. It must not have a spaceBoundary.
279280
*/
280281
portion feature spaceBoundary: Occurrence[0..1] subsets spaceShots {
281282
feature redefines isClosed = true;
@@ -286,7 +287,8 @@ package Occurrences {
286287
*/
287288
feature spaceBoundaryOf: Occurrence[0..*] subsets spaceShotOf;
288289

289-
inv { isClosed implies contains(self.unionsOf, union(spaceBoundary, spaceInterior)) }
290+
inv { !isClosed implies contains(self.unionsOf, union(spaceBoundary, spaceInterior)) }
291+
inv { innerSpaceDimension == 0 implies isEmpty(spaceBoundary) }
290292

291293
connector :OutsideOf
292294
from separateSpaceToo :> spaceInterior [0..1]
@@ -476,8 +478,8 @@ package Occurrences {
476478
* SnapshotsOf asserts one occurrence is a snapshot of another.
477479
*/
478480
assoc SnapshotOf specializes TimeSliceOf {
479-
end feature snapshotOcccurrence: Occurrence[1..*] redefines timeSliceOccurrence subsets snapshottedOccurrence.snapshots;
480-
end feature snapshottedOccurrence: Occurrence[0..*] redefines timeSlicedOccurrence subsets snapshotOcccurrence.snapshotOf;
481+
end feature snapshotOccurrence: Occurrence[1..*] redefines timeSliceOccurrence subsets snapshottedOccurrence.snapshots;
482+
end feature snapshottedOccurrence: Occurrence[0..*] redefines timeSlicedOccurrence subsets snapshotOccurrence.snapshotOf;
481483
}
482484

483485
/**
@@ -498,8 +500,10 @@ package Occurrences {
498500
* it spaceShottedOccurrence.
499501
*/
500502
assoc SpaceShotOf specializes SpaceSliceOf {
501-
end feature spaceShotOcccurrence: Occurrence[1..*] redefines spaceSliceOccurrence subsets spaceShottedOccurrence.spaceShots;
502-
end feature spaceShottedOccurrence: Occurrence[1..*] redefines spaceSlicedOccurrence subsets spaceShotOcccurrence.spaceShotOf;
503+
end feature spaceShotOccurrence: Occurrence[1..*] redefines spaceSliceOccurrence subsets spaceShottedOccurrence.spaceShots;
504+
end feature spaceShottedOccurrence: Occurrence[1..*] redefines spaceSlicedOccurrence subsets spaceShotOccurrence.spaceShotOf;
505+
506+
inv { spaceShotOccurrence.innerSpaceDimension < spaceShottedOccurrence.innerSpaceDimension }
503507
}
504508

505509
/**

sysml/src/examples/Geometry Examples/CarWithShapeAndCSG.sysml

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,30 +6,34 @@ package CarWithShapeAndCSG {
66

77
item def Car :> CompoundSpatialItem {
88
item :>> shape : Cuboid [1] {
9-
/* Quantify faces, etc, by redefining nested features. */
9+
/* Quantify height, etc, by redefining nested features. */
1010
}
1111
part powerSource : Engine [1] :> componentItems;
1212
}
1313

1414
part def Engine :> SpatialItem {
15-
item :>> shape [1];
16-
15+
item :>> shape [1];
16+
1717
/* Specify relative positions of c1 and c2 here. */
1818
private attribute c1Position : VectorQuantityValue;
1919
private attribute c2Position : VectorQuantityValue;
2020

21-
private item c1 : Cylinder, SpatialItem [1] {
22-
/* Quantify faces, etc, by redefining nested features. */
23-
attribute :>> coordinateFrame {
24-
attribute origin = c1Position;
25-
}
26-
}
27-
28-
private item c2 : Cylinder, SpatialItem [1] {
29-
/* Quantify faces, etc, by redefining nested features. */
30-
attribute :>> coordinateFrame {
31-
attribute origin = c2Position;
32-
}
21+
private item c1 : SpatialItem [1] {
22+
item :>> shape : Cylinder [1] {
23+
/* Quantify radius, etc, by redefining nested features. */
24+
}
25+
attribute :>> coordinateFrame {
26+
attribute origin = c1Position;
27+
}
28+
}
29+
30+
private item c2 : SpatialItem [1] {
31+
item :>> shape : Cylinder [1] {
32+
/* Quantify radius, etc, by redefining nested features. */
33+
}
34+
attribute :>> coordinateFrame {
35+
attribute origin = c2Position;
36+
}
3337
}
3438

3539
/* CSG intersection of c1 and c2. */

0 commit comments

Comments
 (0)