Lack of standard for deriving connect-Line style from connector icon
I think that the practice of deriving the styling for a new connect Line-annotation based on connector graphics is more or less a de facto standard. It should be made a proper standard.
(Once there is a standard, the Modelica.UsersGuide.Conventions.Icons should also be updated, but that's an issue for the ModelicaStandardLibrary project.)
As a starting point for the discussion, my understanding that all style attributes should be taken from the first graphical primitive of the connector class' Icon-annotation. Further, these are the attributes that would be transferred to the connect Line-annotation:
lineColor(mapped tocolorof theLine)pattern(why on earth doesFilledShapecall it justpatternand notlinePattern?)lineThickness(mapped tothicknessof theLine)smooth
In particular, none of the properties from GraphicItem are transferred (allowing the primitive to have visible = false if it would disturb the look of the icon). Further, a Line would not be usable, as it has the attributes color and thickness rather than lineColor and lineThickness.
Wouldn't it make a lot of sense to be able to use a Line instead of a filled shape?
I suppose that all compatible connectors are expected to have consistent attributes affecting connection styling, so that it doesn't matter whether attributes are taken from a or b in connect(a, b). Maybe this should be mentioned as a non-normative recommendation in the specification, in addition to clearly recommending it in Modelica.UsersGuide.Conventions.Icons?
I suppose that all compatible connectors are expected to have consistent attributes affecting connection styling, so that it doesn't matter whether attributes are taken from
aorbinconnect(a, b). Maybe this should be mentioned as a non-normative recommendation in the specification, in addition to clearly recommending it inModelica.UsersGuide.Conventions.Icons?
I don't think this is the case when using expandable connectors for buses, see for example Modelica.Mechanics.MultiBody.Examples.Systems.RobotR3.Utilities.AxisType2, where the two ends of connections to the sensors differ.
Right. Could it be as simple as saying that the connection line style should never be inferred from the icon of an expandable connector, so that one doesn't need to worry about styling of the first graphical primitive of an expandable connector icon?
Or that the styling is inferred from the starting/first side of the connection. This allows the user to choose the styling by starting the connection at the corresponding end.
Right. Could it be as simple as saying that the connection line style should never be inferred from the icon of an expandable connector, so that one doesn't need to worry about styling of the first graphical primitive of an expandable connector icon?
That doesn't work when connecting between two expandable connectors, as is also seen in Modelica.Mechanics.MultiBody.Examples.Systems.RobotR3.Utilities.AxisType2 (the two yellow lines).
An alternative would be to prefer another connector, or care whether it is a sub-part or not.
Or that the styling is inferred from the starting/first side of the connection. This allows the user to choose the styling by starting the connection at the corresponding end.
Could possibly do, but I'm not sure if we need to have those details specified.
Or that the styling is inferred from the starting/first side of the connection. This allows the user to choose the styling by starting the connection at the corresponding end.
Could possibly do, but I'm not sure if we need to have those details specified.
Right. It would have been different if the connect-equation didn't have its own Line styling, so that the line would dynamically change style when the connector icon changes. What is needed now is just a convention that gives library developers a tool-independent way of suggesting the Line style for new connections. Perhaps the non-normative recommendation should simply be to make an active choice of Line style hint for every connector icon?
After looking at the Dymola code, let me add a few points to Henrik's description.
- Dymola also sets line color, line pattern and thickness attributes. The others are reset to defaults, including smooth.
- We copy the attributes from the first enabled rectangle or polygon primitive, no others. Not from circles, for example. I'm sure there was a discussion behind that decision, but I have now forgotten the motivation.
- For some obvious cases we do not copy an attribute: line pattern "none" and line thickness <= 0. This means that you can in fact set the color of the connection to a different color from the connector, by using one color as fill color and and different color for line color (with pattern "none").
- We copy the attributes from the first enabled rectangle or polygon primitive, no others. Not from circles, for example. I'm sure there was a discussion behind that decision, but I have now forgotten the motivation.
By enabled, do you mean the absence of visible = false? (Would sound like an unnecessary restriction to me, especially in view of allowing the trick to set LinePattern.None and FillPattern.None – do you remember any motivation behind this restriction?)
- We copy the attributes from the first enabled rectangle or polygon primitive, no others. Not from circles, for example. I'm sure there was a discussion behind that decision, but I have now forgotten the motivation.
By enabled, do you mean the absence of
visible = false? (Would sound like an unnecessary restriction to me, especially in view of allowing the trick to setLinePattern.NoneandFillPattern.None– do you remember any motivation behind this restriction?)
Yes, that's what I mean by enabled (or rather what the comment in the code said). No, I don't remember the motivation anymore. Maybe that visible=false should mean not only out-of-sight but also out-of-mind? It may be an unnecessary restriction, but it's what Dymola does today.
Yes, that's what I mean by enabled (or rather what the comment in the code said). No, I don't remember the motivation anymore. Maybe that
visible=falseshould mean not only out-of-sight but also out-of-mind? It may be an unnecessary restriction, but it's what Dymola does today.
I'd find it useful to drop that restriction, as it would provide a better alternative to hiding a small polygon behind other graphics in case the style isn't appropriate for the graphics item at the bottom of the stack. That way, tools could have dedicated support for indicating the presence of this polygon when editing the connector icon, making it easy to see where the styling comes from (as well as changing it) without having any effect when using the connector. Tools could also offer special ways of setting up this invisible polygon at the bottom of the stack, with an extent that is not (or at least extremely unlikely to be) occluded.
Regarding smooth, this is something we (System Modeler) would very much like to be considered part of the styling.
Regarding
smooth, this is something we (System Modeler) would very much like to be considered part of the styling.
To me a smooth outline of an element in a connector (which is quite small) is quite different from the smooth-ness of the connection-line.
Note that only attributes that are set should be copied.
Tool vendors that are interested in providing input to this discussion are welcome to show the result of making a connection between the two components in this model:
model DefaultConnectLineStyle
connector C
annotation(Diagram(coordinateSystem(extent = {{-100, -100}, {100, 100}}, preserveAspectRatio = true, initialScale = 0.1, grid = {10, 10})), Icon(coordinateSystem(extent = {{-2, -2}, {2, 2}}, preserveAspectRatio = true, initialScale = 1, grid = {0.1, 0.1}), graphics = {Polygon(visible = true, origin = {0.618, -0}, lineColor = {255, 0, 255}, fillColor = {0, 255, 0}, pattern = LinePattern.Dot, fillPattern = FillPattern.CrossDiag, lineThickness = 0.5, points = {{-0.818, -1.5}, {-1.49, -0}, {-0.818, 1.5}, {1.382, 1.5}, {0.182, 0.5}, {0.182, -0.5}, {1.382, -1.5}}, smooth = Smooth.Bezier)}));
end C;
model M
C c annotation(Placement(visible = true, transformation(origin = {104.488, -1.416}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {10, -0}, extent = {{-2, -2}, {2, 2}}, rotation = 0)));
annotation(Diagram(coordinateSystem(extent = {{-100, -100}, {100, 100}}, preserveAspectRatio = true, initialScale = 0.1, grid = {10, 10})), Icon(coordinateSystem(extent = {{-10, -10}, {10, 10}}, preserveAspectRatio = true, initialScale = 1, grid = {1, 1}), graphics = {Rectangle(visible = true, fillColor = {255, 255, 255}, fillPattern = FillPattern.Solid, extent = {{-10, -10}, {10, 10}})}));
end M;
M m1 annotation(Placement(visible = true, transformation(origin = {30, 30}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
M m2 annotation(Placement(visible = true, transformation(origin = {70, 70}, extent = {{-10, -10}, {10, 10}}, rotation = -450)));
annotation(Diagram(coordinateSystem(extent = {{10, 10}, {90, 90}}, preserveAspectRatio = true, initialScale = 0.1, grid = {5, 5})), Icon(coordinateSystem(extent = {{-100, -100}, {100, 100}}, preserveAspectRatio = true, initialScale = 0.1, grid = {10, 10}), graphics = {Rectangle(visible = true, lineColor = {0, 114, 195}, fillColor = {255, 255, 255}, extent = {{-100, -100}, {100, 100}}, radius = 25), Text(visible = true, textColor = {64, 64, 64}, extent = {{-150, 110}, {150, 150}}, textString = "%name")}));
end DefaultConnectLineStyle;
For convenience, the Polygon of the connector icon is repeated here:
Polygon(
lineColor = {255, 0, 255},
fillColor = {0, 255, 0},
pattern = LinePattern.Dot,
fillPattern = FillPattern.CrossDiag,
lineThickness = 0.5,
smooth = Smooth.Bezier,
origin = …,
points = …
)
This is what the diagram looks like before adding the connection:
In a development build of System Modeler, the resulting line is picking up all the style attributes mentioned above:
connect(m1.c, m2.c)
annotation(Line(
visible = true,
origin = {60, 40},
points = {{-20, -10}, {10, -10}, {10, 20}},
color = {255, 0, 255},
pattern = LinePattern.Dot,
thickness = 0.5,
smooth = Smooth.Bezier
));
That we set visible is a tool-specific behavior that should be disregarded for purposes of this investigation.
Edit: I've corrected the thickness value since the original posting of this comment.
Dymola 2023x Refresh 1 (!), the last official release gives you this connection.
connect(m1.c, m2.c)
annotation (Line(
points={{40,30},{70,30},{70,60}},
color={255,0,255},
pattern=LinePattern.Dot,
thickness=0.5));
My development version of Dymola gives:
connect(m1.c, m2.c)
annotation (Line(
points={{40,30},{70,30},{70,60}},
color={255,0,255},
pattern=LinePattern.Dot,
thickness=0.5,
smooth=Smooth.Bezier));
Our development versions seem similar @henrikt-ma, except for the thickness attribute. Please enlighten me.
Our development versions seem similar @henrikt-ma, except for the thickness attribute. Please enlighten me.
That was my bad. That was the original lineThickness of my example, but I later changed it to get more reasonable looks. I've now corrected the reported behavior for System Modeler, making it consistent with what you report for the development version of Dymola.
Pinging some people who might be interested in representing other tools: @sjoelund, @gkurzbach, @eshmoylova, @MarkusOlssonModelon
Adding @adeas31 to the loop, he's the one who develops the GUI
In OpenModelica we only use the color attribute so for the above example we produce,
connect(m1.c, m2.c) annotation(
Line(points = {{40, 30}, {70, 30}, {70, 60}}, color = {255, 0, 255}));
Adding other attributes in the development version gives,
connect(m2.c, m1.c) annotation(
Line(points = {{40, 30}, {70, 30}, {70, 60}}, color = {255, 0, 255}, pattern = LinePattern.Dot, smooth = Smooth.Bezier));
Note that the lineThickness is not included since we have a special handling for it.
Only set the connection line thickness to 0.5 when both connectors are either expandable or (array && !connectorSizing). Otherwise set it to 0.25 i.e., default.
Note that the
lineThicknessis not included since we have a special handling for it.Only set the connection line thickness to 0.5 when both connectors are either expandable or (array && !connectorSizing). Otherwise set it to 0.25 i.e., default.
Alright, so here we have something that needs to be resolved. I can understand that line thickness is the most controversial attribute to pick from the connector icon since I can see that leaving the control to the tool has clear advantages, such as keeping the same width in pixels regardless of magnification on screen.
Some alternative resolutions come to mind:
- (a) Specify that
lineThicknessshould be considered, but update MSL connector icons and style guide so that the first polygon does not specifylineThickness. - (b) Exclude
lineThicknessfrom the attributes to pick up. - (c) Pick up
thicknessfrom the firstLinewithvisible = falseinstead.
I find (a) problematic, since it makes the first polygon less useful as a visible part of the connectors icon due to the inability to set lineThickness without unwanted consequences.
The problem with (b), of course, is that it gives the library author no control over the connection line thickness.
The reason that (c) requires visible = false is to avoid unwanted consequences for existing connector icons.
In MapleSim, we pick up the color attribute only.
connect(M1.c, M2.c) annotation(Line(points={{550.0,-30.0},{550.0,-130.0},{440.0,-130.0}},color={255,0,255},smooth=Smooth.None));
From the discussion with the developers, we specifically pick up the color from the connector that you click on first to draw the line. Usually, when the connector type match the colors also match.
We stumbled upon this again. I was asked to bring forward a request for the use of an annotation to solve this properly:
- Use a
connectLine-annotation to go side by side withicon, for exampleconnectLine(thickness = 0.5, color = {255, 0, 255}). - When a
connectionLine-annotation is present, no connect-line styling is taken fromicon. - When there is no
connectionLine-annotation, take a small selection of attributes from the first Polygon in theicon; the smaller the better, as it avoids conflicting interpretation with the looks of the connector. At least, excludelineThicknessbased on the discussion above.
When there is no connectionLine-annotation, take a small selection of attributes from the first Polygon in the icon; the smaller the better, as it avoids conflicting interpretation with the looks of the connector. At least, exclude lineThickness based on the discussion above.
Shouldn't it be the first graphical primitive instead of Polygon?
Shouldn't it be the first graphical primitive instead of Polygon?
Considering the conversation above, I think the only alternative which would be relevant in view of what tools to today would be to say Polygon or Rectangle.
Well if we are talking about standardization then we should not consider it in the context of a tool. Lets say you can have components with just ellipses and lines. So the first graphical primitive makes sense or the first one that extends from FilledShape.
Just being curious: What about something like Modelica.Blocks.Interfaces.RealVectorInput?
Well if we are talking about standardization then we should not consider it in the context of a tool. Lets say you can have components with just ellipses and lines. So the first graphical primitive makes sense or the first one that extends from
FilledShape.
My proposal is to define an annotation as the primary method; the only reason for specifying a fallback based on some graphical primitive would be to give stronger support for the legacy solution. I would also be fine with not specifying the legacy solution at all, putting more pressure on library developers to adopt the much cleaner annotation approach.
Just being curious: What about something like
Modelica.Blocks.Interfaces.RealVectorInput?
Apparently Dymola will use some default connect-line styling in this case. System Modeler, on the other hand, is picking up the color also in this case. Seems like a mess to standardize behavior for the Ellipse today, considering that libraries developed with Dymola could be full of ellipses that were not meant to affect connect-line styling.
We stumbled upon this again. I was asked to bring forward a request for the use of an annotation to solve this properly:
Can you elaborate what you stumbled on, and how hard? I'm not convinced this is a problem we need to solve, or at least that it is of significantly lower importance than many other aspects of Modelica. And it is not free: it has to be implemented, it needs UI to set up (I have no idea how that would be done), it must be documented.