ModelicaSpecification icon indicating copy to clipboard operation
ModelicaSpecification copied to clipboard

Lack of standard for deriving connect-Line style from connector icon

Open henrikt-ma opened this issue 2 years ago • 33 comments

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.)

henrikt-ma avatar May 17 '23 10:05 henrikt-ma

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 to color of the Line)
  • pattern (why on earth does FilledShape call it just pattern and not linePattern?)
  • lineThickness (mapped to thickness of the Line)
  • 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?

henrikt-ma avatar May 17 '23 10:05 henrikt-ma

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?

henrikt-ma avatar May 17 '23 14:05 henrikt-ma

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 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.

maltelenz avatar May 17 '23 14:05 maltelenz

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?

henrikt-ma avatar May 17 '23 20:05 henrikt-ma

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.

maltelenz avatar May 22 '23 08:05 maltelenz

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.

HansOlsson avatar May 22 '23 09:05 HansOlsson

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?

henrikt-ma avatar May 25 '23 21:05 henrikt-ma

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").

DagBruck avatar May 26 '23 06:05 DagBruck

  • 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?)

henrikt-ma avatar May 29 '23 12:05 henrikt-ma

  • 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?)

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.

DagBruck avatar Jun 02 '23 08:06 DagBruck

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.

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.

henrikt-ma avatar Jun 07 '23 12:06 henrikt-ma

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.

HansOlsson avatar Jun 07 '23 13:06 HansOlsson

Note that only attributes that are set should be copied.

HansOlsson avatar Jun 07 '23 14:06 HansOlsson

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: before-connect

henrikt-ma avatar Jun 08 '23 09:06 henrikt-ma

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.

henrikt-ma avatar Jun 08 '23 10:06 henrikt-ma

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));

DagBruck avatar Jun 10 '23 10:06 DagBruck

Our development versions seem similar @henrikt-ma, except for the thickness attribute. Please enlighten me.

DagBruck avatar Jun 10 '23 10:06 DagBruck

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

henrikt-ma avatar Jun 11 '23 20:06 henrikt-ma

Adding @adeas31 to the loop, he's the one who develops the GUI

casella avatar Jun 12 '23 09:06 casella

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.

adeas31 avatar Jun 12 '23 13:06 adeas31

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.

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 lineThickness should be considered, but update MSL connector icons and style guide so that the first polygon does not specify lineThickness.
  • (b) Exclude lineThickness from the attributes to pick up.
  • (c) Pick up thickness from the first Line with visible = false instead.

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.

henrikt-ma avatar Jun 13 '23 06:06 henrikt-ma

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.

eshmoylova avatar Jun 13 '23 13:06 eshmoylova

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 with icon, for example connectLine(thickness = 0.5, color = {255, 0, 255}).
  • When a connectionLine-annotation is present, no connect-line styling is taken from icon.
  • 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.

henrikt-ma avatar Mar 01 '24 16:03 henrikt-ma

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?

adeas31 avatar Mar 04 '24 09:03 adeas31

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.

henrikt-ma avatar Mar 07 '24 15:03 henrikt-ma

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.

adeas31 avatar Mar 07 '24 15:03 adeas31

Just being curious: What about something like Modelica.Blocks.Interfaces.RealVectorInput?

gwr-de avatar Mar 07 '24 15:03 gwr-de

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.

henrikt-ma avatar Mar 07 '24 15:03 henrikt-ma

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.

henrikt-ma avatar Mar 07 '24 15:03 henrikt-ma

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.

DagBruck avatar Mar 14 '24 15:03 DagBruck