CadQuery / CQ-editor

CadQuery GUI editor based on PyQT
Apache License 2.0
752 stars 114 forks source link

Behavior of the view-buttons (menu-bar) #393

Closed Paul8043 closed 1 year ago

Paul8043 commented 1 year ago

I did some exercises to become more familiar with cq-editor and discovered some strange behavior. I want to show this with a small code-snippet. The code below creates a labeled cube. Each side has been named according to the direction of the corresponding axis. "+Y" means, I am looking from the rear. If I am walking around the cube (with mouse dragging), all faces look fine.

# Topic: behavior of view-buttons

import cadquery as cq

part = cq.Workplane("XY").box(20,20,20)

part = part.faces("<Z").workplane(centerOption="CenterOfMass").text("-Z",5,-1)
part = part.faces(">Z").workplane(centerOption="CenterOfMass").text("+Z",5,-1)
part = part.faces("<X").workplane(centerOption="CenterOfMass").text("-X",5,-1)
part = part.faces(">X").workplane(centerOption="CenterOfMass").text("+X",5,-1)
part = part.faces("<Y").workplane(centerOption="CenterOfMass").text("-Y",5,-1)
part = part.faces(">Y").workplane(centerOption="CenterOfMass").text("+Y",5,-1)

bottom = part.faces("<Z")
top    = part.faces(">Z")
left   = part.faces("<X")
right  = part.faces(">X")
front  = part.faces("<Y")
back   = part.faces(">Y")

show_object(part,name="part",options={"alpha":0.0,"color":(255,170,0)})

#debug(bottom,name="bottom")
#debug(top,name="top")
#debug(left,name="left")
#debug(right,name="right")
debug(front,name="front")
#debug(back,name="back")

#rotated = bottom.rotate([0,0,0],[0,0,1],180)
#show_object(rotated,name="rotated",options={"alpha":0.0,"color":(0,128,0)})

# Behavior:
# Top    (Shift F3): +Z
# Bottom (Shift F4): Z-  !!! upside-down !!!
# Front  (Shift F5): +Y  !!! back !!!
# Back   (Shift F6): -Y  !!! front !!!
# Left   (Shift F7): -X
# Right  (Shift F8): +X

This behavior is totally unexpected. Top-Button, Left-Button and Right-Button behave normally, but the remaining buttons show a very strange behavior. Bottom-Button shows the right side, but the contents is shown upside-down. Front-Button shows the rear-side and Back-Button shows the front-side. This is very confusing.

BTW, the axis-indicator says the Y-axis goes to the rear. In the case the axis-indicator is wrong and Y-axis actually points to the front, then Front-Button and Back-Button would show the right thing, but this would not solve the issue with the Bottom-Button.

BTW, is the direction of the Y-axis hard-coded inside cadquery or can this be customized? Some other viewers have decided to use the other setup (Y-axis pointing to the front). Is there a simple way to flip the axis, or more precisely asked to flip the the model, so that it fits to the chosen axis-orientation? In the OpenSCAD-world the scale([1,-1,1]) should be sufficient to so solve the problem. What is the counter-part in cadquery?

I hope this can be fixed soon.

adam-urbanczyk commented 1 year ago

front = part.faces("<Y") is not front but back. Everything is working as intended.

Paul8043 commented 1 year ago

This is a very subtle issue. CadQuery is still a new tool for me. I know it for about only 3 weeks. During this time I had to process a lot of information. I could not cover everything in detail. Some conceptions are still growing, and the axis-orientation is part of it. I take big care that the conceptions in my brain are right from the very beginning. Any kind of mismatches are bothering me to the uttermost. I have continued my investigation. The devil is in the details, amostly in the hidden ones. I was able to find the root-cause for this irritation: some lack of information together with a wrong expectation. Below is the clarified code.

You are right, everything is ok and is working as indended.

# Topic: behavior of view-buttons

import cadquery as cq

part = cq.Workplane("XY").box(30,30,30)

part = part.faces("<Z").workplane(centerOption="CenterOfMass").text("bottom",5,-1)  # bottom
part = part.faces(">Z").workplane(centerOption="CenterOfMass").text("top",5,-1)     # top
part = part.faces("<X").workplane(centerOption="CenterOfMass").text("left",5,-1)    # left
part = part.faces(">X").workplane(centerOption="CenterOfMass").text("right",5,-1)   # right
part = part.faces("<Y").workplane(centerOption="CenterOfMass").text("back",5,-1)    # back
part = part.faces(">Y").workplane(centerOption="CenterOfMass").text("front",5,-1)   # front

bottom = part.faces("<Z")
top    = part.faces(">Z")
left   = part.faces("<X")
right  = part.faces(">X")
back   = part.faces("<Y")
front  = part.faces(">Y")

show_object(part,name="part",options={"alpha":0.0,"color":(255,170,0)})

debug(front,name="front")

# Behavior:
# Iso    (Shift+F2): back-top-right   !!! no front !!!
# Top    (Shift F3): top
# Bottom (Shift F4): bottom           !!! upside-down !!!
# Front  (Shift F5): front
# Back   (Shift F6): back
# Left   (Shift F7): left
# Right  (Shift F8): right

I never asked myself, what the "Iso (Shift+F2)" is showing. I have assumed that I would see the front-side, but this is not true. It shows back-top-right!

Sorry for bothering you, your are absolutely right, everything is working as intended. The buttons perform the right action, the axis-indicator is also correct, and the selector(">Y") belongs to the positive y-axis. All is right with the world again.

I am very glad that this behavior has got natural explanation.

May be this behavior can be included somewhere in the documentation. The probability that newcomers stumble at this point is quite high. (It took me 3 days to understand the behavior.)

alexer commented 1 week ago

@adam-urbanczyk I think this was closed prematurely (or there has been a regression) - it looks to me like the buttons for front and back view are indeed swapped.

I think we can agree that if you look at the front face with the top face facing up, the right face should be on the right side (like it is on eg. Fusion 360 and FreeCAD). That is not how it works in CQ-editor at the moment.

If one only has "Z+" etc. written on the faces, like in the first post, I think it isn't immediately obvious (at least to me) that there's something wrong - but if you use "TOP" etc., like in the last post, I think the issue becomes pretty clear.

This first snippet creates the cube I described earlier (ie. with the front facing the viewer and the top facing up, right will be facing right - see the image), oriented such that the top view button shows the top face and the right view button shows the right face. If you click the "front" view button, however, it will show the back face.

```python import cadquery as cq sides = { 'RIGHT': '>X', 'LEFT': 'Y', 'FRONT': 'Z', 'BOTTOM': ' ![cq_sides](https://github.com/user-attachments/assets/150cbfc9-7492-48f3-a589-1d497601d94c)

This second snippet only swaps the front and back, creating a cube such that each view button will show a face with the same text as the view button you clicked - but you end up with a cube such that if you look at the front face, with the top face pointing up, the face with "left" written on it will be on the right. (See the bottom image)

```python import cadquery as cq sides = { 'RIGHT': '>X', 'LEFT': 'Y', 'TOP': '>Z', 'BOTTOM': ' ![cq_sides_flipped](https://github.com/user-attachments/assets/bfa45be0-e9e2-4450-97d0-6843e6318b30) ![cq_sides_flipped_rotated](https://github.com/user-attachments/assets/d1657cff-ec44-4922-a997-b44fc594c25b)
adam-urbanczyk commented 1 week ago

AFAICT <Y is not front but back.

alexer commented 1 week ago

@adam-urbanczyk I mean, the second snippet puts "BACK" at <Y - but if you look at the screenshots of that, don't they look obviously wrong? (ie. the "LEFT" face will be on the right when looking at the "FRONT" with the "TOP" up - it definitely doesn't match what you see in other CAD programs)

adam-urbanczyk commented 1 week ago

Which screenshot of which model in which view looks obviously wrong?

alexer commented 1 week ago

@adam-urbanczyk The bottom-most screenshot (on the bottom-most model/snippet - ie. where "BACK" is at <Y like you say) - "LEFT" ends up on the right side, when looking at the "FRONT", with the "TOP" up.

adam-urbanczyk commented 1 week ago

Did you look at the trihedron? LEFT is <X so all is fine.

alexer commented 1 week ago

@adam-urbanczyk Let's ignore the axes and axis directions for a moment - you don't need to bring those into the picture to see the problem. Let me try to put this in another way:

I've colored the top/front/right view icon faces blue/green/red, and colored the same faces in the first cube, just so you can more easily see their relative positioning (so the orientation of the actual isometric view is irrelevant to this): cq_cube_icons_colored

If you then click each of the three colored buttons, and color the face which is shown with the same color (ignore the texts on the faces, they aren't relevant to my point), you end up with this: cq_sides_rotated_colored

Compare the order of the colors in the cube you ended up with, with the order of the colors in the view buttons - no matter how you rotate the cube, you can't get the colors in the same order, ie. the view button icons cannot be consistent with what they do.

adam-urbanczyk commented 1 week ago

@adam-urbanczyk Let's ignore the axes and axis directions for a moment - you don't need to bring those into the picture to see the problem. Let me try to put this in another way:

AFAICT the view is consistent with the trihedron orientation. BTW you colored the faces not according to the used convention (i.e. >Y is front).

alexer commented 1 week ago

@adam-urbanczyk I colored the faces of the view icons that were already highlighted, so if I colored the wrong face there, the wrong face is highlighted in the icons. I colored the same faces on the viewed object that the view buttons showed me (again, ignore the text, I did not color based on that, but based on what the view buttons showed me), so if the colors are wrong there, then the buttons took me to the wrong view. Again: the problem is more basic - you do not need to look at the trihedron orientation, or the axis directions to see the problem - ignore them for just a second.

adam-urbanczyk commented 1 week ago

For the model below if I click the buttons: top, bottom, front, back, left, right (cf. tooltips or menu View) I do see the corresponding text. What is the problem?

import cadquery as cq

sides = {
    'RIGHT': '>X',
    'LEFT': '<X',
    'BACK': '<Y',
    'FRONT': '>Y',
    'TOP': '>Z',
    'BOTTOM': '<Z',
}

part = cq.Workplane("XY").box(10, 10, 10)
for side, facesel in sides.items():
    part = part.faces(facesel).workplane(centerOption="CenterOfMass").text(side, 2, -.05)
alexer commented 1 week ago

@adam-urbanczyk Click the buttons "Top", "Front" and "Right". Try to rotate the cube into an orientation where the three faces that are shown are in the same locations than in the view buttons you clicked, all at the same time: you can't.

If you rotate the cube so that all three of those faces are shown, they will be in a different order than the highlighted faces in the view cube icons. You will end up with eg. "TOP" at the top, "RIGHT" on the left, and "FRONT" on the right, whereas on the view cube icons "TOP" would be at the top, "FRONT" would be on the left and "RIGHT" would be on the right.

Note the difference, ie. that the "RIGHT"/"FRONT" are in different places on the view cube icons and in the displayed object.

adam-urbanczyk commented 1 week ago

So what you mean is: icons are swapped, not the buttons (cf. tooltips/names in the menu).

alexer commented 1 week ago

@adam-urbanczyk Well, the order of the texts in the model you used just now is also different from other CAD software: view_cubes (Ie. if you orient the top and front like in the picture, then "LEFT" will be on the right side instead of "RIGHT")

So based on that, I'd argue that ">Y" should be "BACK" to be consistent with other software. (And I assume mechanical engineering in general, but I have no experience, so can't say with any confidence) Ie. I think the sign of the non-zero v.SetProj() argument should be reversed in back_view() and front_view() in widgets/viewer.py.

But that is, in some sense, a convention ("if you're looking at the front of an object that is not upside down, then the object's right side is on the right") - though I'd say it's a very common convention. (A notable other way of looking at it is from the perspective of the object, eg. looking from inside the object to outside of the object, like in a car - then the left/right would swap)

So, while I think the change I suggested makes the most sense, I concede that there are other ways one could look at it (though I think it's indisputable that something must change, since currently clicking the icons doesn't move you to the view that is shown).