CadQuery / cadquery

A python parametric CAD scripting framework based on OCCT
https://cadquery.readthedocs.io
Other
2.97k stars 280 forks source link

Assembly Color Component Values in Exported STEP File Are Shifted #794

Closed jmwright closed 3 years ago

jmwright commented 3 years ago

If I run the following code I expect to get a STEP file that has an RGB for the box of (0.5, 0.5, 0.5), but I see (0.735356983052,0.735356983052,0.735356983052) instead.

import cadquery as cq

assy = cq.Assembly()

box = cq.Workplane().box(10, 10, 10)

assy.add(box, color=cq.Color(0.5, 0.5, 0.5, 1))

assy.save("/home/jwright/Downloads/color_test.step")

Here is the RGB line within the resulting STEP file:

#451 = COLOUR_RGB('',0.735356983052,0.735356983052,0.735356983052);

Changing the alpha value does not seem to make a difference, and I've tried two different versions of CadQuery that are from after the assembly addition. They both do the same thing.

The effect of this is that it causes validation errors when comparing CQ 2.x generated STEPs to the originals that have been checked by hand by the KiCAD team.

Another glitch that might be related is that the colors in the original KiCAD models are recognized by FreeCAD when the STEP is imported, but the colors in our exported STEP files are ignored. I don't know if this has something to do with the way layers are handled by the OCCT export process.

Here is the full output of the resulting STEP file.

ISO-10303-21;
HEADER;
FILE_DESCRIPTION(('Open CASCADE Model'),'2;1');
FILE_NAME('Open CASCADE Shape Model','2021-06-21T15:22:04',('Author'),(
    'Open CASCADE'),'Open CASCADE STEP processor 7.5','Open CASCADE 7.5'
  ,'Unknown');
FILE_SCHEMA(('AUTOMOTIVE_DESIGN { 1 0 10303 214 1 1 1 1 }'));
ENDSEC;
DATA;
#1 = APPLICATION_PROTOCOL_DEFINITION('international standard',
  'automotive_design',2000,#2);
#2 = APPLICATION_CONTEXT(
  'core data for automotive mechanical design processes');
#3 = SHAPE_DEFINITION_REPRESENTATION(#4,#10);
#4 = PRODUCT_DEFINITION_SHAPE('','',#5);
#5 = PRODUCT_DEFINITION('design','',#6,#9);
#6 = PRODUCT_DEFINITION_FORMATION('','',#7);
#7 = PRODUCT('CQ assembly','CQ assembly','',(#8));
#8 = PRODUCT_CONTEXT('',#2,'mechanical');
#9 = PRODUCT_DEFINITION_CONTEXT('part definition',#2,'design');
#10 = SHAPE_REPRESENTATION('',(#11,#15),#19);
#11 = AXIS2_PLACEMENT_3D('',#12,#13,#14);
#12 = CARTESIAN_POINT('',(0.,0.,0.));
#13 = DIRECTION('',(0.,0.,1.));
#14 = DIRECTION('',(1.,0.,-0.));
#15 = AXIS2_PLACEMENT_3D('',#16,#17,#18);
#16 = CARTESIAN_POINT('',(0.,0.,0.));
#17 = DIRECTION('',(0.,0.,1.));
#18 = DIRECTION('',(1.,0.,-0.));
#19 = ( GEOMETRIC_REPRESENTATION_CONTEXT(3) 
GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#23)) GLOBAL_UNIT_ASSIGNED_CONTEXT(
(#20,#21,#22)) REPRESENTATION_CONTEXT('Context #1',
  '3D Context with UNIT and UNCERTAINTY') );
#20 = ( LENGTH_UNIT() NAMED_UNIT(*) SI_UNIT(.MILLI.,.METRE.) );
#21 = ( NAMED_UNIT(*) PLANE_ANGLE_UNIT() SI_UNIT($,.RADIAN.) );
#22 = ( NAMED_UNIT(*) SI_UNIT($,.STERADIAN.) SOLID_ANGLE_UNIT() );
#23 = UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(1.E-07),#20,
  'distance_accuracy_value','confusion accuracy');
#24 = PRODUCT_RELATED_PRODUCT_CATEGORY('part',$,(#7));
#25 = SHAPE_DEFINITION_REPRESENTATION(#26,#32);
#26 = PRODUCT_DEFINITION_SHAPE('','',#27);
#27 = PRODUCT_DEFINITION('design','',#28,#31);
#28 = PRODUCT_DEFINITION_FORMATION('','',#29);
#29 = PRODUCT('f6464f20-d2c5-11eb-b9c5-54ee75e79fa7',
  'f6464f20-d2c5-11eb-b9c5-54ee75e79fa7','',(#30));
#30 = PRODUCT_CONTEXT('',#2,'mechanical');
#31 = PRODUCT_DEFINITION_CONTEXT('part definition',#2,'design');
#32 = SHAPE_REPRESENTATION('',(#11,#33,#37),#41);
#33 = AXIS2_PLACEMENT_3D('',#34,#35,#36);
#34 = CARTESIAN_POINT('',(0.,0.,0.));
#35 = DIRECTION('',(0.,0.,1.));
#36 = DIRECTION('',(1.,0.,-0.));
#37 = AXIS2_PLACEMENT_3D('',#38,#39,#40);
#38 = CARTESIAN_POINT('',(0.,0.,0.));
#39 = DIRECTION('',(0.,0.,1.));
#40 = DIRECTION('',(1.,0.,-0.));
#41 = ( GEOMETRIC_REPRESENTATION_CONTEXT(3) 
GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#45)) GLOBAL_UNIT_ASSIGNED_CONTEXT(
(#42,#43,#44)) REPRESENTATION_CONTEXT('Context #1',
  '3D Context with UNIT and UNCERTAINTY') );
#42 = ( LENGTH_UNIT() NAMED_UNIT(*) SI_UNIT(.MILLI.,.METRE.) );
#43 = ( NAMED_UNIT(*) PLANE_ANGLE_UNIT() SI_UNIT($,.RADIAN.) );
#44 = ( NAMED_UNIT(*) SI_UNIT($,.STERADIAN.) SOLID_ANGLE_UNIT() );
#45 = UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(1.E-07),#42,
  'distance_accuracy_value','confusion accuracy');
#46 = SHAPE_REPRESENTATION('',(#11),#47);
#47 = ( GEOMETRIC_REPRESENTATION_CONTEXT(3) 
GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#51)) GLOBAL_UNIT_ASSIGNED_CONTEXT(
(#48,#49,#50)) REPRESENTATION_CONTEXT('Context #1',
  '3D Context with UNIT and UNCERTAINTY') );
#48 = ( LENGTH_UNIT() NAMED_UNIT(*) SI_UNIT(.MILLI.,.METRE.) );
#49 = ( NAMED_UNIT(*) PLANE_ANGLE_UNIT() SI_UNIT($,.RADIAN.) );
#50 = ( NAMED_UNIT(*) SI_UNIT($,.STERADIAN.) SOLID_ANGLE_UNIT() );
#51 = UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(1.E-07),#48,
  'distance_accuracy_value','confusion accuracy');
#52 = SHAPE_DEFINITION_REPRESENTATION(#53,#46);
#53 = PRODUCT_DEFINITION_SHAPE('','',#54);
#54 = PRODUCT_DEFINITION('design','',#55,#58);
#55 = PRODUCT_DEFINITION_FORMATION('','',#56);
#56 = PRODUCT('f6464f20-d2c5-11eb-b9c5-54ee75e79fa7_part',
  'f6464f20-d2c5-11eb-b9c5-54ee75e79fa7_part','',(#57));
#57 = PRODUCT_CONTEXT('',#2,'mechanical');
#58 = PRODUCT_DEFINITION_CONTEXT('part definition',#2,'design');
#59 = CONTEXT_DEPENDENT_SHAPE_REPRESENTATION(#60,#62);
#60 = ( REPRESENTATION_RELATIONSHIP('','',#46,#32) 
REPRESENTATION_RELATIONSHIP_WITH_TRANSFORMATION(#61) 
SHAPE_REPRESENTATION_RELATIONSHIP() );
#61 = ITEM_DEFINED_TRANSFORMATION('','',#11,#33);
#62 = PRODUCT_DEFINITION_SHAPE('Placement','Placement of an item',#63);
#63 = NEXT_ASSEMBLY_USAGE_OCCURRENCE('5','','',#27,#54,$);
#64 = PRODUCT_RELATED_PRODUCT_CATEGORY('part',$,(#56));
#65 = SHAPE_DEFINITION_REPRESENTATION(#66,#72);
#66 = PRODUCT_DEFINITION_SHAPE('','',#67);
#67 = PRODUCT_DEFINITION('design','',#68,#71);
#68 = PRODUCT_DEFINITION_FORMATION('','',#69);
#69 = PRODUCT('f6499766-d2c5-11eb-b9c5-54ee75e79fa7',
  'f6499766-d2c5-11eb-b9c5-54ee75e79fa7','',(#70));
#70 = PRODUCT_CONTEXT('',#2,'mechanical');
#71 = PRODUCT_DEFINITION_CONTEXT('part definition',#2,'design');
#72 = SHAPE_REPRESENTATION('',(#11,#73),#77);
#73 = AXIS2_PLACEMENT_3D('',#74,#75,#76);
#74 = CARTESIAN_POINT('',(0.,0.,0.));
#75 = DIRECTION('',(0.,0.,1.));
#76 = DIRECTION('',(1.,0.,-0.));
#77 = ( GEOMETRIC_REPRESENTATION_CONTEXT(3) 
GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#81)) GLOBAL_UNIT_ASSIGNED_CONTEXT(
(#78,#79,#80)) REPRESENTATION_CONTEXT('Context #1',
  '3D Context with UNIT and UNCERTAINTY') );
#78 = ( LENGTH_UNIT() NAMED_UNIT(*) SI_UNIT(.MILLI.,.METRE.) );
#79 = ( NAMED_UNIT(*) PLANE_ANGLE_UNIT() SI_UNIT($,.RADIAN.) );
#80 = ( NAMED_UNIT(*) SI_UNIT($,.STERADIAN.) SOLID_ANGLE_UNIT() );
#81 = UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(1.E-07),#78,
  'distance_accuracy_value','confusion accuracy');
#82 = ADVANCED_BREP_SHAPE_REPRESENTATION('',(#11,#83),#413);
#83 = MANIFOLD_SOLID_BREP('',#84);
#84 = CLOSED_SHELL('',(#85,#205,#305,#352,#399,#406));
#85 = ADVANCED_FACE('',(#86),#100,.F.);
#86 = FACE_BOUND('',#87,.F.);
#87 = EDGE_LOOP('',(#88,#123,#151,#179));
#88 = ORIENTED_EDGE('',*,*,#89,.F.);
#89 = EDGE_CURVE('',#90,#92,#94,.T.);
#90 = VERTEX_POINT('',#91);
#91 = CARTESIAN_POINT('',(-5.,-5.,-5.));
#92 = VERTEX_POINT('',#93);
#93 = CARTESIAN_POINT('',(-5.,-5.,5.));
#94 = SURFACE_CURVE('',#95,(#99,#111),.PCURVE_S1.);
#95 = LINE('',#96,#97);
#96 = CARTESIAN_POINT('',(-5.,-5.,-5.));
#97 = VECTOR('',#98,1.);
#98 = DIRECTION('',(0.,0.,1.));
#99 = PCURVE('',#100,#105);
#100 = PLANE('',#101);
#101 = AXIS2_PLACEMENT_3D('',#102,#103,#104);
#102 = CARTESIAN_POINT('',(-5.,-5.,-5.));
#103 = DIRECTION('',(1.,0.,0.));
#104 = DIRECTION('',(0.,0.,1.));
#105 = DEFINITIONAL_REPRESENTATION('',(#106),#110);
#106 = LINE('',#107,#108);
#107 = CARTESIAN_POINT('',(0.,0.));
#108 = VECTOR('',#109,1.);
#109 = DIRECTION('',(1.,0.));
#110 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
  ) );
#111 = PCURVE('',#112,#117);
#112 = PLANE('',#113);
#113 = AXIS2_PLACEMENT_3D('',#114,#115,#116);
#114 = CARTESIAN_POINT('',(-5.,-5.,-5.));
#115 = DIRECTION('',(0.,1.,0.));
#116 = DIRECTION('',(0.,0.,1.));
#117 = DEFINITIONAL_REPRESENTATION('',(#118),#122);
#118 = LINE('',#119,#120);
#119 = CARTESIAN_POINT('',(0.,0.));
#120 = VECTOR('',#121,1.);
#121 = DIRECTION('',(1.,0.));
#122 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
  ) );
#123 = ORIENTED_EDGE('',*,*,#124,.T.);
#124 = EDGE_CURVE('',#90,#125,#127,.T.);
#125 = VERTEX_POINT('',#126);
#126 = CARTESIAN_POINT('',(-5.,5.,-5.));
#127 = SURFACE_CURVE('',#128,(#132,#139),.PCURVE_S1.);
#128 = LINE('',#129,#130);
#129 = CARTESIAN_POINT('',(-5.,-5.,-5.));
#130 = VECTOR('',#131,1.);
#131 = DIRECTION('',(0.,1.,0.));
#132 = PCURVE('',#100,#133);
#133 = DEFINITIONAL_REPRESENTATION('',(#134),#138);
#134 = LINE('',#135,#136);
#135 = CARTESIAN_POINT('',(0.,0.));
#136 = VECTOR('',#137,1.);
#137 = DIRECTION('',(0.,-1.));
#138 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
  ) );
#139 = PCURVE('',#140,#145);
#140 = PLANE('',#141);
#141 = AXIS2_PLACEMENT_3D('',#142,#143,#144);
#142 = CARTESIAN_POINT('',(-5.,-5.,-5.));
#143 = DIRECTION('',(0.,0.,1.));
#144 = DIRECTION('',(1.,0.,0.));
#145 = DEFINITIONAL_REPRESENTATION('',(#146),#150);
#146 = LINE('',#147,#148);
#147 = CARTESIAN_POINT('',(0.,0.));
#148 = VECTOR('',#149,1.);
#149 = DIRECTION('',(0.,1.));
#150 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
  ) );
#151 = ORIENTED_EDGE('',*,*,#152,.T.);
#152 = EDGE_CURVE('',#125,#153,#155,.T.);
#153 = VERTEX_POINT('',#154);
#154 = CARTESIAN_POINT('',(-5.,5.,5.));
#155 = SURFACE_CURVE('',#156,(#160,#167),.PCURVE_S1.);
#156 = LINE('',#157,#158);
#157 = CARTESIAN_POINT('',(-5.,5.,-5.));
#158 = VECTOR('',#159,1.);
#159 = DIRECTION('',(0.,0.,1.));
#160 = PCURVE('',#100,#161);
#161 = DEFINITIONAL_REPRESENTATION('',(#162),#166);
#162 = LINE('',#163,#164);
#163 = CARTESIAN_POINT('',(0.,-10.));
#164 = VECTOR('',#165,1.);
#165 = DIRECTION('',(1.,0.));
#166 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
  ) );
#167 = PCURVE('',#168,#173);
#168 = PLANE('',#169);
#169 = AXIS2_PLACEMENT_3D('',#170,#171,#172);
#170 = CARTESIAN_POINT('',(-5.,5.,-5.));
#171 = DIRECTION('',(0.,1.,0.));
#172 = DIRECTION('',(0.,0.,1.));
#173 = DEFINITIONAL_REPRESENTATION('',(#174),#178);
#174 = LINE('',#175,#176);
#175 = CARTESIAN_POINT('',(0.,0.));
#176 = VECTOR('',#177,1.);
#177 = DIRECTION('',(1.,0.));
#178 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
  ) );
#179 = ORIENTED_EDGE('',*,*,#180,.F.);
#180 = EDGE_CURVE('',#92,#153,#181,.T.);
#181 = SURFACE_CURVE('',#182,(#186,#193),.PCURVE_S1.);
#182 = LINE('',#183,#184);
#183 = CARTESIAN_POINT('',(-5.,-5.,5.));
#184 = VECTOR('',#185,1.);
#185 = DIRECTION('',(0.,1.,0.));
#186 = PCURVE('',#100,#187);
#187 = DEFINITIONAL_REPRESENTATION('',(#188),#192);
#188 = LINE('',#189,#190);
#189 = CARTESIAN_POINT('',(10.,0.));
#190 = VECTOR('',#191,1.);
#191 = DIRECTION('',(0.,-1.));
#192 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
  ) );
#193 = PCURVE('',#194,#199);
#194 = PLANE('',#195);
#195 = AXIS2_PLACEMENT_3D('',#196,#197,#198);
#196 = CARTESIAN_POINT('',(-5.,-5.,5.));
#197 = DIRECTION('',(0.,0.,1.));
#198 = DIRECTION('',(1.,0.,0.));
#199 = DEFINITIONAL_REPRESENTATION('',(#200),#204);
#200 = LINE('',#201,#202);
#201 = CARTESIAN_POINT('',(0.,0.));
#202 = VECTOR('',#203,1.);
#203 = DIRECTION('',(0.,1.));
#204 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
  ) );
#205 = ADVANCED_FACE('',(#206),#220,.T.);
#206 = FACE_BOUND('',#207,.T.);
#207 = EDGE_LOOP('',(#208,#238,#261,#284));
#208 = ORIENTED_EDGE('',*,*,#209,.F.);
#209 = EDGE_CURVE('',#210,#212,#214,.T.);
#210 = VERTEX_POINT('',#211);
#211 = CARTESIAN_POINT('',(5.,-5.,-5.));
#212 = VERTEX_POINT('',#213);
#213 = CARTESIAN_POINT('',(5.,-5.,5.));
#214 = SURFACE_CURVE('',#215,(#219,#231),.PCURVE_S1.);
#215 = LINE('',#216,#217);
#216 = CARTESIAN_POINT('',(5.,-5.,-5.));
#217 = VECTOR('',#218,1.);
#218 = DIRECTION('',(0.,0.,1.));
#219 = PCURVE('',#220,#225);
#220 = PLANE('',#221);
#221 = AXIS2_PLACEMENT_3D('',#222,#223,#224);
#222 = CARTESIAN_POINT('',(5.,-5.,-5.));
#223 = DIRECTION('',(1.,0.,0.));
#224 = DIRECTION('',(0.,0.,1.));
#225 = DEFINITIONAL_REPRESENTATION('',(#226),#230);
#226 = LINE('',#227,#228);
#227 = CARTESIAN_POINT('',(0.,0.));
#228 = VECTOR('',#229,1.);
#229 = DIRECTION('',(1.,0.));
#230 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
  ) );
#231 = PCURVE('',#112,#232);
#232 = DEFINITIONAL_REPRESENTATION('',(#233),#237);
#233 = LINE('',#234,#235);
#234 = CARTESIAN_POINT('',(0.,10.));
#235 = VECTOR('',#236,1.);
#236 = DIRECTION('',(1.,0.));
#237 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
  ) );
#238 = ORIENTED_EDGE('',*,*,#239,.T.);
#239 = EDGE_CURVE('',#210,#240,#242,.T.);
#240 = VERTEX_POINT('',#241);
#241 = CARTESIAN_POINT('',(5.,5.,-5.));
#242 = SURFACE_CURVE('',#243,(#247,#254),.PCURVE_S1.);
#243 = LINE('',#244,#245);
#244 = CARTESIAN_POINT('',(5.,-5.,-5.));
#245 = VECTOR('',#246,1.);
#246 = DIRECTION('',(0.,1.,0.));
#247 = PCURVE('',#220,#248);
#248 = DEFINITIONAL_REPRESENTATION('',(#249),#253);
#249 = LINE('',#250,#251);
#250 = CARTESIAN_POINT('',(0.,0.));
#251 = VECTOR('',#252,1.);
#252 = DIRECTION('',(0.,-1.));
#253 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
  ) );
#254 = PCURVE('',#140,#255);
#255 = DEFINITIONAL_REPRESENTATION('',(#256),#260);
#256 = LINE('',#257,#258);
#257 = CARTESIAN_POINT('',(10.,0.));
#258 = VECTOR('',#259,1.);
#259 = DIRECTION('',(0.,1.));
#260 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
  ) );
#261 = ORIENTED_EDGE('',*,*,#262,.T.);
#262 = EDGE_CURVE('',#240,#263,#265,.T.);
#263 = VERTEX_POINT('',#264);
#264 = CARTESIAN_POINT('',(5.,5.,5.));
#265 = SURFACE_CURVE('',#266,(#270,#277),.PCURVE_S1.);
#266 = LINE('',#267,#268);
#267 = CARTESIAN_POINT('',(5.,5.,-5.));
#268 = VECTOR('',#269,1.);
#269 = DIRECTION('',(0.,0.,1.));
#270 = PCURVE('',#220,#271);
#271 = DEFINITIONAL_REPRESENTATION('',(#272),#276);
#272 = LINE('',#273,#274);
#273 = CARTESIAN_POINT('',(0.,-10.));
#274 = VECTOR('',#275,1.);
#275 = DIRECTION('',(1.,0.));
#276 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
  ) );
#277 = PCURVE('',#168,#278);
#278 = DEFINITIONAL_REPRESENTATION('',(#279),#283);
#279 = LINE('',#280,#281);
#280 = CARTESIAN_POINT('',(0.,10.));
#281 = VECTOR('',#282,1.);
#282 = DIRECTION('',(1.,0.));
#283 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
  ) );
#284 = ORIENTED_EDGE('',*,*,#285,.F.);
#285 = EDGE_CURVE('',#212,#263,#286,.T.);
#286 = SURFACE_CURVE('',#287,(#291,#298),.PCURVE_S1.);
#287 = LINE('',#288,#289);
#288 = CARTESIAN_POINT('',(5.,-5.,5.));
#289 = VECTOR('',#290,1.);
#290 = DIRECTION('',(0.,1.,0.));
#291 = PCURVE('',#220,#292);
#292 = DEFINITIONAL_REPRESENTATION('',(#293),#297);
#293 = LINE('',#294,#295);
#294 = CARTESIAN_POINT('',(10.,0.));
#295 = VECTOR('',#296,1.);
#296 = DIRECTION('',(0.,-1.));
#297 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
  ) );
#298 = PCURVE('',#194,#299);
#299 = DEFINITIONAL_REPRESENTATION('',(#300),#304);
#300 = LINE('',#301,#302);
#301 = CARTESIAN_POINT('',(10.,0.));
#302 = VECTOR('',#303,1.);
#303 = DIRECTION('',(0.,1.));
#304 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
  ) );
#305 = ADVANCED_FACE('',(#306),#112,.F.);
#306 = FACE_BOUND('',#307,.F.);
#307 = EDGE_LOOP('',(#308,#329,#330,#351));
#308 = ORIENTED_EDGE('',*,*,#309,.F.);
#309 = EDGE_CURVE('',#90,#210,#310,.T.);
#310 = SURFACE_CURVE('',#311,(#315,#322),.PCURVE_S1.);
#311 = LINE('',#312,#313);
#312 = CARTESIAN_POINT('',(-5.,-5.,-5.));
#313 = VECTOR('',#314,1.);
#314 = DIRECTION('',(1.,0.,0.));
#315 = PCURVE('',#112,#316);
#316 = DEFINITIONAL_REPRESENTATION('',(#317),#321);
#317 = LINE('',#318,#319);
#318 = CARTESIAN_POINT('',(0.,0.));
#319 = VECTOR('',#320,1.);
#320 = DIRECTION('',(0.,1.));
#321 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
  ) );
#322 = PCURVE('',#140,#323);
#323 = DEFINITIONAL_REPRESENTATION('',(#324),#328);
#324 = LINE('',#325,#326);
#325 = CARTESIAN_POINT('',(0.,0.));
#326 = VECTOR('',#327,1.);
#327 = DIRECTION('',(1.,0.));
#328 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
  ) );
#329 = ORIENTED_EDGE('',*,*,#89,.T.);
#330 = ORIENTED_EDGE('',*,*,#331,.T.);
#331 = EDGE_CURVE('',#92,#212,#332,.T.);
#332 = SURFACE_CURVE('',#333,(#337,#344),.PCURVE_S1.);
#333 = LINE('',#334,#335);
#334 = CARTESIAN_POINT('',(-5.,-5.,5.));
#335 = VECTOR('',#336,1.);
#336 = DIRECTION('',(1.,0.,0.));
#337 = PCURVE('',#112,#338);
#338 = DEFINITIONAL_REPRESENTATION('',(#339),#343);
#339 = LINE('',#340,#341);
#340 = CARTESIAN_POINT('',(10.,0.));
#341 = VECTOR('',#342,1.);
#342 = DIRECTION('',(0.,1.));
#343 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
  ) );
#344 = PCURVE('',#194,#345);
#345 = DEFINITIONAL_REPRESENTATION('',(#346),#350);
#346 = LINE('',#347,#348);
#347 = CARTESIAN_POINT('',(0.,0.));
#348 = VECTOR('',#349,1.);
#349 = DIRECTION('',(1.,0.));
#350 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
  ) );
#351 = ORIENTED_EDGE('',*,*,#209,.F.);
#352 = ADVANCED_FACE('',(#353),#168,.T.);
#353 = FACE_BOUND('',#354,.T.);
#354 = EDGE_LOOP('',(#355,#376,#377,#398));
#355 = ORIENTED_EDGE('',*,*,#356,.F.);
#356 = EDGE_CURVE('',#125,#240,#357,.T.);
#357 = SURFACE_CURVE('',#358,(#362,#369),.PCURVE_S1.);
#358 = LINE('',#359,#360);
#359 = CARTESIAN_POINT('',(-5.,5.,-5.));
#360 = VECTOR('',#361,1.);
#361 = DIRECTION('',(1.,0.,0.));
#362 = PCURVE('',#168,#363);
#363 = DEFINITIONAL_REPRESENTATION('',(#364),#368);
#364 = LINE('',#365,#366);
#365 = CARTESIAN_POINT('',(0.,0.));
#366 = VECTOR('',#367,1.);
#367 = DIRECTION('',(0.,1.));
#368 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
  ) );
#369 = PCURVE('',#140,#370);
#370 = DEFINITIONAL_REPRESENTATION('',(#371),#375);
#371 = LINE('',#372,#373);
#372 = CARTESIAN_POINT('',(0.,10.));
#373 = VECTOR('',#374,1.);
#374 = DIRECTION('',(1.,0.));
#375 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
  ) );
#376 = ORIENTED_EDGE('',*,*,#152,.T.);
#377 = ORIENTED_EDGE('',*,*,#378,.T.);
#378 = EDGE_CURVE('',#153,#263,#379,.T.);
#379 = SURFACE_CURVE('',#380,(#384,#391),.PCURVE_S1.);
#380 = LINE('',#381,#382);
#381 = CARTESIAN_POINT('',(-5.,5.,5.));
#382 = VECTOR('',#383,1.);
#383 = DIRECTION('',(1.,0.,0.));
#384 = PCURVE('',#168,#385);
#385 = DEFINITIONAL_REPRESENTATION('',(#386),#390);
#386 = LINE('',#387,#388);
#387 = CARTESIAN_POINT('',(10.,0.));
#388 = VECTOR('',#389,1.);
#389 = DIRECTION('',(0.,1.));
#390 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
  ) );
#391 = PCURVE('',#194,#392);
#392 = DEFINITIONAL_REPRESENTATION('',(#393),#397);
#393 = LINE('',#394,#395);
#394 = CARTESIAN_POINT('',(0.,10.));
#395 = VECTOR('',#396,1.);
#396 = DIRECTION('',(1.,0.));
#397 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
  ) );
#398 = ORIENTED_EDGE('',*,*,#262,.F.);
#399 = ADVANCED_FACE('',(#400),#140,.F.);
#400 = FACE_BOUND('',#401,.F.);
#401 = EDGE_LOOP('',(#402,#403,#404,#405));
#402 = ORIENTED_EDGE('',*,*,#124,.F.);
#403 = ORIENTED_EDGE('',*,*,#309,.T.);
#404 = ORIENTED_EDGE('',*,*,#239,.T.);
#405 = ORIENTED_EDGE('',*,*,#356,.F.);
#406 = ADVANCED_FACE('',(#407),#194,.T.);
#407 = FACE_BOUND('',#408,.T.);
#408 = EDGE_LOOP('',(#409,#410,#411,#412));
#409 = ORIENTED_EDGE('',*,*,#180,.F.);
#410 = ORIENTED_EDGE('',*,*,#331,.T.);
#411 = ORIENTED_EDGE('',*,*,#285,.T.);
#412 = ORIENTED_EDGE('',*,*,#378,.F.);
#413 = ( GEOMETRIC_REPRESENTATION_CONTEXT(3) 
GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#417)) GLOBAL_UNIT_ASSIGNED_CONTEXT
((#414,#415,#416)) REPRESENTATION_CONTEXT('Context #1',
  '3D Context with UNIT and UNCERTAINTY') );
#414 = ( LENGTH_UNIT() NAMED_UNIT(*) SI_UNIT(.MILLI.,.METRE.) );
#415 = ( NAMED_UNIT(*) PLANE_ANGLE_UNIT() SI_UNIT($,.RADIAN.) );
#416 = ( NAMED_UNIT(*) SI_UNIT($,.STERADIAN.) SOLID_ANGLE_UNIT() );
#417 = UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(1.E-07),#414,
  'distance_accuracy_value','confusion accuracy');
#418 = SHAPE_DEFINITION_REPRESENTATION(#419,#82);
#419 = PRODUCT_DEFINITION_SHAPE('','',#420);
#420 = PRODUCT_DEFINITION('design','',#421,#424);
#421 = PRODUCT_DEFINITION_FORMATION('','',#422);
#422 = PRODUCT('f6499766-d2c5-11eb-b9c5-54ee75e79fa7_part',
  'f6499766-d2c5-11eb-b9c5-54ee75e79fa7_part','',(#423));
#423 = PRODUCT_CONTEXT('',#2,'mechanical');
#424 = PRODUCT_DEFINITION_CONTEXT('part definition',#2,'design');
#425 = CONTEXT_DEPENDENT_SHAPE_REPRESENTATION(#426,#428);
#426 = ( REPRESENTATION_RELATIONSHIP('','',#82,#72) 
REPRESENTATION_RELATIONSHIP_WITH_TRANSFORMATION(#427) 
SHAPE_REPRESENTATION_RELATIONSHIP() );
#427 = ITEM_DEFINED_TRANSFORMATION('','',#11,#73);
#428 = PRODUCT_DEFINITION_SHAPE('Placement','Placement of an item',#429
  );
#429 = NEXT_ASSEMBLY_USAGE_OCCURRENCE('6','','',#67,#420,$);
#430 = PRODUCT_RELATED_PRODUCT_CATEGORY('part',$,(#422));
#431 = CONTEXT_DEPENDENT_SHAPE_REPRESENTATION(#432,#434);
#432 = ( REPRESENTATION_RELATIONSHIP('','',#72,#32) 
REPRESENTATION_RELATIONSHIP_WITH_TRANSFORMATION(#433) 
SHAPE_REPRESENTATION_RELATIONSHIP() );
#433 = ITEM_DEFINED_TRANSFORMATION('','',#11,#37);
#434 = PRODUCT_DEFINITION_SHAPE('Placement','Placement of an item',#435
  );
#435 = NEXT_ASSEMBLY_USAGE_OCCURRENCE('7','','',#27,#67,$);
#436 = PRODUCT_RELATED_PRODUCT_CATEGORY('part',$,(#69));
#437 = CONTEXT_DEPENDENT_SHAPE_REPRESENTATION(#438,#440);
#438 = ( REPRESENTATION_RELATIONSHIP('','',#32,#10) 
REPRESENTATION_RELATIONSHIP_WITH_TRANSFORMATION(#439) 
SHAPE_REPRESENTATION_RELATIONSHIP() );
#439 = ITEM_DEFINED_TRANSFORMATION('','',#11,#15);
#440 = PRODUCT_DEFINITION_SHAPE('Placement','Placement of an item',#441
  );
#441 = NEXT_ASSEMBLY_USAGE_OCCURRENCE('8','','',#5,#27,$);
#442 = PRODUCT_RELATED_PRODUCT_CATEGORY('part',$,(#29));
#443 = MECHANICAL_DESIGN_GEOMETRIC_PRESENTATION_REPRESENTATION('',(#444)
  ,#413);
#444 = STYLED_ITEM('color',(#445),#83);
#445 = PRESENTATION_STYLE_ASSIGNMENT((#446));
#446 = SURFACE_STYLE_USAGE(.BOTH.,#447);
#447 = SURFACE_SIDE_STYLE('',(#448));
#448 = SURFACE_STYLE_FILL_AREA(#449);
#449 = FILL_AREA_STYLE('',(#450));
#450 = FILL_AREA_STYLE_COLOUR('',#451);
#451 = COLOUR_RGB('',0.735356983052,0.735356983052,0.735356983052);
ENDSEC;
END-ISO-10303-21;
adam-urbanczyk commented 3 years ago

I tried importing an assy using FC 0.20 and I can see the colors. I checked the imported color value form the dark red object and it is [165,0,53] ~ [ 0.647, 0, 0.208] which is as expected (module the rounding). The alpha has indeed no effect (this is even mentioned in the docs AFAIR) - I was assuming (maybe wrongly) that it is not a part of the STEP spec.

import cadquery as cq

w = 10
d = 10
h = 10

part1 = cq.Workplane().box(2*w,2*d,h)
part2 = cq.Workplane().box(w,d,2*h)
part3 = cq.Workplane().box(w,d,3*h)

assy = (
    cq.Assembly(part1, loc=cq.Location(cq.Vector(-w,0,h/2)))
    .add(part2, loc=cq.Location(cq.Vector(1.5*w,-.5*d,h/2)), color=cq.Color(0.65,0,.21,1))
    .add(part3, loc=cq.Location(cq.Vector(-.5*w,-.5*d,2*h)), color=cq.Color("red"))

)

assy

image image

adam-urbanczyk commented 3 years ago

Also your model has [127,127,127] in FC 0.20.

jmwright commented 3 years ago

Here is my hacked code from occ_impl.assembly.Color that corrects the color shift from our side, albeit with some very slight rounding error in the final STEP. Visually it's impossible to tell the difference between the original and the new STEP file though.

def __init__(self, *args, **kwargs):

        if len(args) == 1:
            self.wrapped = Quantity_ColorRGBA()
            exists = Quantity_ColorRGBA.ColorFromName_s(args[0], self.wrapped)
            if not exists:
                raise ValueError(f"Unknown color name: {args[0]}")
        elif len(args) == 3:
            r, g, b = args
            self.wrapped = Quantity_Color(r, g, b ,Quantity_TOC_sRGB) #Quantity_ColorRGBA(r, g, b, 1)
            # if kwargs.get("a"):
            #     self.wrapped.SetAlpha(kwargs.get("a"))
        elif len(args) == 4:
            r, g, b, a = args
            self.wrapped = Quantity_Color(r, g, b ,Quantity_TOC_sRGB) #Quantity_ColorRGBA(r, g, b, a)
        else:
            raise ValueError(f"Unsupported arguments: {args}, {kwargs}")

    def toTuple(self) -> Tuple[float, float, float, float]:
        """
        Convert Color to RGB tuple.
        """
        # a = self.wrapped.Alpha()
        a = 1
        # rgb = self.wrapped.GetRGB()

        return (self.Red(), self.Green(), self.Blue(), a)

So now the question becomes, am I correcting an actual problem, or just hacking around a difference between the KiCAD viewer and OCCT's current STEP exporter?

@adam-urbanczyk I would be interested in learning more about the example you had where the STEP colors did not look right in the online viewer. With my hack the colors do not come out right when the STEP is exported into FreeCAD. I may have to end up just overriding the assembly.Color type for the KiCAD generator as a one-off, and make it so that it's easy to disable in the future when things align on our side and theirs.

jmwright commented 3 years ago

Here is the STEP import code for KiCAD, and it doesn't look like anything out of the ordinary is being done. https://gitlab.com/kicad/code/kicad/-/blob/master/utils/kicad2step/pcb/oce_utils.cpp#L1271

I have version 5.1 installed from the Ubuntu PPA and it lists "OpenCASCADE Community Edition: 6.9.1" as the OpenCascade version/fork that's being used. I think that is where this color mismatch is coming from. I'll add code to work around this issue that can be easily disabled later when they update their OpenCascade dependency. In their install documentation they say that OCCT >= 6.9.0 can be used during the build process, but I don't know if the newer versions of OCCT have been tried.

adam-urbanczyk commented 3 years ago

So they are still using OCE, weird? And 6.9 is really outdated. Once they switch to OCCT 7.5 the issue might go away.

jmwright commented 3 years ago

I was just told that they've deprecated OCE in favor of OCCT, and the Mac and Windows nightly builds use 7.5.2. I'm going to switch to running the nightly Ubuntu build to see if these problems go away.

jmwright commented 3 years ago

The STEP color shift problem persists on KiCAD's nightly Ubuntu build, and the VRML exports do not import correctly, although they look fine in FreeCAD and the view3dscene tool in Ubuntu. I'll post more targeted issues when I have enough information.

adam-urbanczyk commented 3 years ago

And if you use Quantity_TOC_sRGB then for both versions the colors are fine?

jmwright commented 3 years ago

Yes, doing it this way seems to work fine for the STEP colors within the KiCAD viewer. FreeCAD 0.19 and 0.20 (freecad-daily) both refuse to display the colors though. I can send you the STEP file if you want to take a look.

adam-urbanczyk commented 3 years ago

Please do send the file. It might be a FC issue.