FreeCAD / FreeCAD

This is the official source code of FreeCAD, a free and opensource multiplatform 3D parametric modeler.
https://www.freecad.org
Other
19.83k stars 4.06k forks source link

Shape color is not displayed correctly after change in tree #6069

Open FreeCAD-Bug-Importer opened 2 years ago

FreeCAD-Bug-Importer commented 2 years ago

Issue imported from https://tracker.freecad.org/view.php?id=4357

Original report text

Modifying the tree by dragging elements in, breaks the color of the shape on screen, although it's still set in the part.

Steps to reproduce

  1. Part Module
  2. Make 5 Cubes (translate sligthly to get overlaps)
  3. Select Cube 1&2 and make Boolean Fragments 1 (BF1)
  4. Select Cube 3&4 and make Boolean Fragments 2 (BF2)
  5. Select BF1, CTRL-Select BF2 > Make boolean intersection (CUT)
  6. Select CUT > View > Set any Shape Color (red)
  7. In Treeview, drag Cube 5 into BF2 and recompute

    CUT will be shown in default color, although CUT>View will still show the set color (red)

FreeCAD Info

OS: Windows 10
Word size of OS: 64-bit
Word size of FreeCAD: 64-bit
Version: 0.18.4 (GitTag)
Build type: Release
Branch: releases/FreeCAD-0-18
Hash: 980bf9060e28555fecd9e3462f68ca74007b70f8
Python version: 3.6.6
Qt version: 5.6.2
Coin version: 4.0.0a
OCC version: 7.3.0
Locale: German/Switzerland (de_CH)

Other bug information

Discussion from Mantis ticket

Comment by openBrain 2020-06-04 18:11

sangue : please address your issue following our reporting guidelines by opening first a topic in our forum. Thx We generally accept tickets when issue has been vet by the community, and especially confirmed to still exist in current development version (which you can test by yourself).


Comment by Kunda1 2020-06-07 14:20

sangue forum thread please


Comment by sangue 2020-06-08 07:53

Yep. Just couldn't add another post earlier, cause forum didn't let me. It's here now: https://forum.freecadweb.org/viewtopic.php?f=19&t=47394

luzpaz commented 2 years ago

User on the forum has offered a workaround macro:

# -*- coding: utf-8 -*-
import FreeCAD

selection = FreeCADGui.Selection.getSelection()
for item in selection:
    tempColor = item.ViewObject.ShapeColor
    transparency = item.ViewObject.Transparency
    # Invert the color of all selected shapes.
    item.ViewObject.ShapeColor = (1 - tempColor[0], 1 - tempColor[1], 1 - tempColor[2])
    item.ViewObject.Transparency = 100 - item.ViewObject.Transparency
    # Reset the original color.
    item.ViewObject.ShapeColor = tempColor 
    item.ViewObject.Transparency = transparency
luzpaz commented 2 years ago

Bumped forum thread for activity

onekk commented 10 months ago

Issue still present see this test code:

"""shapecolor_bug.py

   This code was written as an sample code 

   Author: Carlo Dormeletti
   Copyright: 2021
   Licence: CC BY-NC-ND 4.0 IT 
"""

import os
import os.path
import math

import FreeCAD
from FreeCAD import Placement, Rotation, Vector
import Part

DOC_NAME = "shapecolor_bug"

DOC = FreeCAD.activeDocument()

def clear_doc():
    """
    Clear the active document deleting all the objects
    """
    for obj in DOC.Objects:
        try:
            DOC.removeObject(obj.Name)
        except Exception:
            pass

def create_doc(doc_name):
    obj = FreeCAD.newDocument(doc_name)
    return obj.Name

def setview():
    """Rearrange View"""
    DOC.recompute()
    VIEW.viewAxometric()
    VIEW.setAxisCross(True)
    VIEW.fitAll()

print(DOC)

if DOC is None:
    obj = create_doc(DOC_NAME)
    FreeCAD.setActiveDocument(obj)
    DOC = FreeCAD.activeDocument()
    VIEW = FreeCAD.Gui.ActiveDocument.ActiveView

else:
    if DOC.Name != DOC_NAME:
        obj = create_doc(DOC_NAME)
        FreeCAD.setActiveDocument(obj)
        DOC = FreeCAD.activeDocument()
        VIEW = FreeCAD.Gui.ActiveDocument.ActiveView
    else:
        DOC = FreeCAD.activeDocument()
        clear_doc()
        VIEW = FreeCAD.Gui.ActiveDocument.ActiveView

EPS = 0.10
EPS_C = EPS * -0.5

VZOR = Vector(0,0,0)
ROT0 = Rotation(0, 0, 0)

box_o = DOC.addObject('Part::Feature', 'outer_Box')
box_o.Shape = Part.makeBox(30, 30, 10)

box_i = DOC.addObject('Part::Feature', 'inner_Box')
box_i.Shape = Part.makeBox(20, 20, 11)
box_i.Placement = Placement(Vector(5, 5, -0.5), ROT0)

DOC.recompute()

cut_obj = DOC.addObject('Part::Cut', 'cut_object')
cut_obj.Base = box_o
cut_obj.Tool = box_i
cut_obj.Refine = True

cut_obj.ViewObject.ShapeColor = (1.0, 0.5, 0.0)

DOC.recompute()

setview()

print("--- done ---")

Kind Regards

Carlo D.

Roy-043 commented 10 months ago

AFAIK this is intended behavior. The result of a Part boolean operation inherits its face colors from its source objects. This sets the DiffuseColor which overrides the ShapeColor of an object.

The obvious workaround is to change the color of the source objects. Alternatively a Draft_Clone or a Part_RefineShape can be create from the Cut, and that new object given the desired ShapeColor.

onekk commented 10 months ago

Not to be polemic, but this IMHO even worse, see:

"""shapecolor_bug.py

   This code was written as an sample code 

   Author: Carlo Dormeletti
   Copyright: 2021
   Licence: CC BY-NC-ND 4.0 IT 
"""

import os
import os.path
import math

import FreeCAD
from FreeCAD import Placement, Rotation, Vector
import Part

DOC_NAME = "shapecolor_bug"

DOC = FreeCAD.activeDocument()

def clear_doc():
    """
    Clear the active document deleting all the objects
    """
    for obj in DOC.Objects:
        try:
            DOC.removeObject(obj.Name)
        except Exception:
            pass

def create_doc(doc_name):
    obj = FreeCAD.newDocument(doc_name)
    return obj.Name

def setview():
    """Rearrange View"""
    DOC.recompute()
    VIEW.viewAxometric()
    VIEW.setAxisCross(True)
    VIEW.fitAll()

print(DOC)

if DOC is None:
    obj = create_doc(DOC_NAME)
    FreeCAD.setActiveDocument(obj)
    DOC = FreeCAD.activeDocument()
    VIEW = FreeCAD.Gui.ActiveDocument.ActiveView

else:
    if DOC.Name != DOC_NAME:
        obj = create_doc(DOC_NAME)
        FreeCAD.setActiveDocument(obj)
        DOC = FreeCAD.activeDocument()
        VIEW = FreeCAD.Gui.ActiveDocument.ActiveView
    else:
        DOC = FreeCAD.activeDocument()
        clear_doc()
        VIEW = FreeCAD.Gui.ActiveDocument.ActiveView

EPS = 0.10
EPS_C = EPS * -0.5

VZOR = Vector(0,0,0)
ROT0 = Rotation(0, 0, 0)

box_o = DOC.addObject('Part::Feature', 'outer_Box')
box_o.Shape = Part.makeBox(30, 30, 10)
box_o.ViewObject.ShapeColor = (1.0, 0.5, 0.0)

box_i = DOC.addObject('Part::Feature', 'inner_Box')
box_i.Shape = Part.makeBox(20, 20, 11)
box_i.Placement = Placement(Vector(5, 5, -0.5), ROT0)
box_i.ViewObject.ShapeColor = (0.5, 0.5, 0.0)

DOC.recompute()

cut_obj = DOC.addObject('Part::Cut', 'cut_object')
cut_obj.Base = box_o
cut_obj.Tool = box_i
cut_obj.Refine = True

# cut_obj.ViewObject.ShapeColor = (1.0, 0.5, 0.0)

DOC.recompute()

setview()

print("--- done ---")

It ineriths color from both source objects, see the example above.

What is an "expected behaviour", i use a cut object and the "cut color" is "transferred" to the part that have been cut?

I know that this is the way FreeCAD has worked till now, but...

Originally the problem has arisen from an example when I have made a cabinet maker software that has different colors for each component of the cabinet.

When I cut objects, the color of the cut objects was transferred to the other object, so I have to asssign explictly the color at the result of the boolean operation.

DiffuseColor sadly is applied per face, so it is a nightmare to reassign it (I've known the procedure, only I've not noted the fact that this happen when making a boolean cut).

I can live with it, as I've done a script that will amend things, sadly it has to be installed as a Macro and run manually after every modification of cabinet dimensions.

Kind Regards

Carlo D.

Roy-043 commented 10 months ago

The current behavior makes some sense if you join two objects that have different colors. For example a red cylinder and a blue box.

My point is not that this request should be closed, but I do not think you can call this a bug. The behavior we see took some programming effort.

Note that you can also cut with the cut method of shapes.

onekk commented 10 months ago

The current behavior makes some sense if you join two objects that have different colors. For example a red cylinder and a blue box.

My point is not that this request should be closed, but I do not think you can call this a bug. The behavior we see took some programming effort.

Note that you can also cut with the cut method of shapes.

The point is that when you cut, an expected behaviour is that the cut color is not taken in account.

In my use case it is not an option to work on TopoShapes as the FCStd file is standalone and should work without relying on scripting (It is generated by a script but it work standalone)

Out of my use case, however:

Kind Regards

Carlo D.

maxwxyz commented 7 months ago

is this still present with the recent material merges? @davesrocketshop FYI

Roy-043 commented 6 months ago

Recent forum topic mentioning this issue: https://forum.freecad.org/viewtopic.php?t=87435