ansys-speos-core 0.5.1__py3-none-any.whl → 0.5.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
ansys/speos/core/bsdf.py CHANGED
@@ -28,6 +28,7 @@ from collections import Counter, UserDict
28
28
  from collections.abc import Collection
29
29
  from pathlib import Path
30
30
  from typing import Union
31
+ import warnings
31
32
 
32
33
  from google.protobuf.empty_pb2 import Empty
33
34
  import grpc
@@ -38,6 +39,7 @@ import ansys.api.speos.bsdf.v1.anisotropic_bsdf_pb2_grpc as anisotropic_bsdf__v1
38
39
  import ansys.api.speos.bsdf.v1.bsdf_creation_pb2 as bsdf_creation__v1__pb2
39
40
  import ansys.api.speos.bsdf.v1.bsdf_creation_pb2_grpc as bsdf_creation__v1__pb2_grpc
40
41
  import ansys.api.speos.bsdf.v1.spectral_bsdf_pb2 as spectral_bsdf__v1__pb2
42
+ import ansys.api.speos.bsdf.v1.spectral_bsdf_pb2_grpc as spectral_bsdf__v1__pb2_grpc
41
43
  import ansys.speos.core
42
44
  from ansys.speos.core.speos import Speos
43
45
 
@@ -50,6 +52,8 @@ class BaseBSDF:
50
52
  speos : ansys.speos.core.speos.Speos
51
53
  stub :
52
54
  grpc stub to connect to BSDF service
55
+ namespace :
56
+ grpc namespace for the bsdf
53
57
 
54
58
  Notes
55
59
  -----
@@ -57,7 +61,7 @@ class BaseBSDF:
57
61
 
58
62
  """
59
63
 
60
- def __init__(self, speos: Speos, stub):
64
+ def __init__(self, speos: Speos, stub, namespace):
61
65
  self.client = speos.client
62
66
  self._stub = stub
63
67
  self._grpcbsdf = None
@@ -65,6 +69,8 @@ class BaseBSDF:
65
69
  self.has_reflection = False
66
70
  self.anisotropy_vector = [1, 0, 0]
67
71
  self.description = ""
72
+ self.__namespace = namespace
73
+ self.__interpolation_settings = None
68
74
 
69
75
  @property
70
76
  def has_transmission(self) -> bool:
@@ -168,6 +174,40 @@ class BaseBSDF:
168
174
  r_angle = []
169
175
  return [r_angle, t_angle]
170
176
 
177
+ @property
178
+ def interpolation_settings(self) -> Union[None, InterpolationEnhancement]:
179
+ """Interpolation enhancement settings of the bsdf file.
180
+
181
+ If bsdf file does not have interpolation enhancement settings, return None.
182
+ if bsdf file has interpolation enhancement settings, return InterpolationEnhancement.
183
+ """
184
+ return self.__interpolation_settings
185
+
186
+ def create_interpolation_enhancement(
187
+ self, index_1: float = 1.0, index_2: float = 1.0
188
+ ) -> InterpolationEnhancement:
189
+ """Apply automatic interpolation enhancement.
190
+
191
+ Return interpolation settings to user if settings need change.
192
+
193
+ Parameters
194
+ ----------
195
+ index_1 : float
196
+ outside refractive index
197
+ index_2 : float
198
+ inside refractive index
199
+
200
+ Returns
201
+ -------
202
+ ansys.speos.core.bsdf._InterpolationEnhancement
203
+ automatic interpolation settings with index_1 = 1 and index_2 = 1 by default.
204
+ """
205
+ self._stub.Import(self._grpcbsdf)
206
+ self.__interpolation_settings = InterpolationEnhancement(
207
+ bsdf=self, bsdf_namespace=self.__namespace, index_1=index_1, index_2=index_2
208
+ )
209
+ return self.__interpolation_settings
210
+
171
211
 
172
212
  class InterpolationEnhancement:
173
213
  """Class to facilitate Specular interpolation enhancement.
@@ -244,7 +284,7 @@ class InterpolationEnhancement:
244
284
 
245
285
  def __init__(
246
286
  self,
247
- bsdf: Union[AnisotropicBSDF],
287
+ bsdf: Union[AnisotropicBSDF, SpectralBRDF],
248
288
  bsdf_namespace: Union[spectral_bsdf__v1__pb2, anisotropic_bsdf__v1__pb2],
249
289
  index_1: Union[float, None] = 1.0,
250
290
  index_2: Union[float, None] = 1.0,
@@ -298,7 +338,7 @@ class InterpolationEnhancement:
298
338
  @property
299
339
  def get_reflection_interpolation_settings(self) -> Union[None, _InterpolationSettings]:
300
340
  """Return a fixed dictionary for reflection interpolation settings to be set by user."""
301
- if self.__cones_data.reflection is None:
341
+ if not self._bsdf.has_reflection:
302
342
  return None
303
343
  if isinstance(self._bsdf, AnisotropicBSDF):
304
344
  reflection_interpolation_settings = self._InterpolationSettings(
@@ -332,8 +372,35 @@ class InterpolationEnhancement:
332
372
  }
333
373
  )
334
374
  return reflection_interpolation_settings
375
+ if isinstance(self._bsdf, SpectralBRDF):
376
+ reflection_interpolation_settings = self._InterpolationSettings(
377
+ {str(key): 0 for key in self._bsdf.wavelength}
378
+ )
379
+ r_angles = list(set(self._bsdf.incident_angles[0]))
380
+ for wl_index, wl in enumerate(self._bsdf.wavelength):
381
+ tmp_reflection_key = str(wl)
382
+ reflection_incident_interpolation_settings = self._InterpolationSettings(
383
+ {str(key): 0 for key in r_angles}
384
+ )
385
+ reflection_interpolation_settings.update(
386
+ {tmp_reflection_key: reflection_incident_interpolation_settings}
387
+ )
388
+ for inc_index, inc in enumerate(r_angles):
389
+ ani_sample = self.__cones_data.wavelength_incidence_samples[
390
+ (wl_index + 1) * inc_index
391
+ ]
392
+ tmp_reflection_incident_key = str(inc)
393
+ reflection_interpolation_settings[str(wl)].update(
394
+ {
395
+ tmp_reflection_incident_key: {
396
+ "half_angle": ani_sample.reflection.cone_half_angle,
397
+ "height": ani_sample.reflection.cone_height,
398
+ }
399
+ }
400
+ )
401
+ return reflection_interpolation_settings
335
402
  else:
336
- raise ValueError("only anistropic bsdf supported")
403
+ raise ValueError("only anisotropic and spectral bsdf supported")
337
404
 
338
405
  def set_interpolation_settings(
339
406
  self, is_brdf: bool, settings: InterpolationEnhancement._InterpolationSettings
@@ -347,17 +414,14 @@ class InterpolationEnhancement:
347
414
  settings: InterpolationEnhancement._InterpolationSettings
348
415
  interpolation settings.
349
416
  """
350
- if self.__cones_data.reflection is None and self.__cones_data.transmission is None:
351
- raise ValueError("does not have reflection or transmission")
352
- if is_brdf and self.__cones_data.reflection is None:
353
- raise ValueError("reflection data is none")
354
- if not is_brdf and self.__cones_data.transmission is None:
355
- raise ValueError("transmission data is none")
356
417
  if not isinstance(
357
418
  settings, ansys.speos.core.bsdf.InterpolationEnhancement._InterpolationSettings
358
419
  ):
359
420
  raise ImportError("only interpolation settings are supported")
360
-
421
+ if is_brdf and not self._bsdf.has_reflection:
422
+ raise ValueError("BSDF has no reflection data")
423
+ if not is_brdf and not self._bsdf.has_transmission:
424
+ raise ValueError("BSDF has no transmission data")
361
425
  if isinstance(self._bsdf, AnisotropicBSDF):
362
426
  self._bsdf._stub.Import(self._bsdf._grpcbsdf)
363
427
  if is_brdf:
@@ -392,13 +456,43 @@ class InterpolationEnhancement:
392
456
  iso_sample_key
393
457
  ][incident_key]["height"]
394
458
  self._bsdf._stub.SetSpecularInterpolationEnhancementData(self.__cones_data)
459
+ elif isinstance(self._bsdf, SpectralBRDF):
460
+ self._bsdf._stub.Import(self._bsdf._grpcbsdf)
461
+ if is_brdf:
462
+ for wl_sample_key_index, wl_sample_key in enumerate(settings.keys()):
463
+ for incident_key_index, incident_key in enumerate(
464
+ settings[wl_sample_key].keys()
465
+ ):
466
+ self.__cones_data.wavelength_incidence_samples[
467
+ (wl_sample_key_index + 1) * incident_key_index
468
+ ].reflection.cone_half_angle = settings[wl_sample_key][incident_key][
469
+ "half_angle"
470
+ ]
471
+ self.__cones_data.wavelength_incidence_samples[
472
+ (wl_sample_key_index + 1) * incident_key_index
473
+ ].reflection.cone_height = settings[wl_sample_key][incident_key]["height"]
474
+ self._bsdf._stub.SetSpecularInterpolationEnhancementData(self.__cones_data)
475
+ else:
476
+ for wl_sample_key_index, wl_sample_key in enumerate(settings.keys()):
477
+ for incident_key_index, incident_key in enumerate(
478
+ settings[wl_sample_key].keys()
479
+ ):
480
+ self.__cones_data.wavelength_incidence_samples[
481
+ (wl_sample_key_index + 1) * incident_key_index
482
+ ].transmission.cone_half_angle = settings[wl_sample_key][incident_key][
483
+ "half_angle"
484
+ ]
485
+ self.__cones_data.wavelength_incidence_samples[
486
+ (wl_sample_key_index + 1) * incident_key_index
487
+ ].transmission.cone_height = settings[wl_sample_key][incident_key]["height"]
488
+ self._bsdf._stub.SetSpecularInterpolationEnhancementData(self.__cones_data)
395
489
  else:
396
- raise ValueError("only anistropic bsdf supported")
490
+ raise ValueError("only anisotropic bsdf and spectral brdf are supported")
397
491
 
398
492
  @property
399
493
  def get_transmission_interpolation_settings(self) -> Union[None, _InterpolationSettings]:
400
494
  """Return a fixed dictionary for reflection interpolation settings to be set by user."""
401
- if self.__cones_data.transmission is None:
495
+ if not self._bsdf.has_transmission:
402
496
  return None
403
497
  if isinstance(self._bsdf, AnisotropicBSDF):
404
498
  transmission_interpolation_settings = self._InterpolationSettings(
@@ -432,9 +526,35 @@ class InterpolationEnhancement:
432
526
  }
433
527
  )
434
528
  return transmission_interpolation_settings
435
-
529
+ if isinstance(self._bsdf, SpectralBRDF):
530
+ transmission_interpolation_settings = self._InterpolationSettings(
531
+ {str(key): 0 for key in self._bsdf.wavelength}
532
+ )
533
+ r_angles = list(set(self._bsdf.incident_angles[0]))
534
+ for wl_index, wl in enumerate(self._bsdf.wavelength):
535
+ tmp_reflection_key = str(wl)
536
+ transmission_incident_interpolation_settings = self._InterpolationSettings(
537
+ {str(key): 0 for key in r_angles}
538
+ )
539
+ transmission_interpolation_settings.update(
540
+ {tmp_reflection_key: transmission_incident_interpolation_settings}
541
+ )
542
+ for inc_index, inc in enumerate(r_angles):
543
+ sample = self.__cones_data.wavelength_incidence_samples[
544
+ (wl_index + 1) * inc_index
545
+ ]
546
+ tmp_reflection_incident_key = str(inc)
547
+ transmission_interpolation_settings[str(wl)].update(
548
+ {
549
+ tmp_reflection_incident_key: {
550
+ "half_angle": sample.transmission.cone_half_angle,
551
+ "height": sample.transmission.cone_height,
552
+ }
553
+ }
554
+ )
555
+ return transmission_interpolation_settings
436
556
  else:
437
- raise ValueError("only anistropic bsdf supported")
557
+ raise ValueError("only anisotropic and spectral bsdf supported")
438
558
 
439
559
 
440
560
  class AnisotropicBSDF(BaseBSDF):
@@ -452,7 +572,9 @@ class AnisotropicBSDF(BaseBSDF):
452
572
 
453
573
  def __init__(self, speos: Speos, file_path: Union[Path, str] = None):
454
574
  super().__init__(
455
- speos, anisotropic_bsdf__v1__pb2_grpc.AnisotropicBsdfServiceStub(speos.client.channel)
575
+ speos,
576
+ anisotropic_bsdf__v1__pb2_grpc.AnisotropicBsdfServiceStub(speos.client.channel),
577
+ anisotropic_bsdf__v1__pb2,
456
578
  )
457
579
  self._spectrum_incidence = [0, 0]
458
580
  self._spectrum_anisotropy = [0, 0]
@@ -465,7 +587,7 @@ class AnisotropicBSDF(BaseBSDF):
465
587
  self._reflection_spectrum, self._transmission_spectrum = self._extract_spectrum()
466
588
  try:
467
589
  self._stub.GetSpecularInterpolationEnhancementData(Empty())
468
- self.__interpolation_settings = InterpolationEnhancement(
590
+ self._BaseBSDF__interpolation_settings = InterpolationEnhancement(
469
591
  bsdf=self,
470
592
  bsdf_namespace=anisotropic_bsdf__v1__pb2,
471
593
  index_1=None,
@@ -475,7 +597,6 @@ class AnisotropicBSDF(BaseBSDF):
475
597
  self.__interpolation_settings = None
476
598
  else:
477
599
  self._transmission_spectrum, self._reflection_spectrum = None, None
478
- self.__interpolation_settings = None
479
600
 
480
601
  def get(self, key=""):
481
602
  """Retrieve any information from the BSDF object.
@@ -709,44 +830,312 @@ class AnisotropicBSDF(BaseBSDF):
709
830
  incidence_diag.bsdf_cos_theta[:] = btdf.bxdf.flatten().tolist()
710
831
  self._stub.Import(bsdf)
711
832
  self._grpcbsdf = bsdf
712
- if self.__interpolation_settings is not None:
833
+ if self._BaseBSDF__interpolation_settings is not None:
713
834
  self._stub.SetSpecularInterpolationEnhancementData(
714
- self.__interpolation_settings._InterpolationEnhancement__cones_data
835
+ self._BaseBSDF__interpolation_settings._InterpolationEnhancement__cones_data
715
836
  )
716
837
 
717
- @property
718
- def interpolation_settings(self) -> Union[None, InterpolationEnhancement]:
719
- """Interpolation enhancement settings of the bsdf file.
838
+ def save(self, file_path: Union[Path, str], commit: bool = True) -> Path:
839
+ """Save a Speos anistropic bsdf.
720
840
 
721
- If bsdf file does not have interpolation enhancement settings, return None.
722
- if bsdf file has interpolation enhancement settings, return InterpolationEnhancement.
841
+ Parameters
842
+ ----------
843
+ file_path : Union[Path, str]
844
+ Filepath to save bsdf
845
+ commit : bool
846
+ commit data before saving
847
+
848
+ Returns
849
+ -------
850
+ Path
851
+ File location
723
852
  """
724
- return self.__interpolation_settings
853
+ file_path = Path(file_path)
854
+ file_name = anisotropic_bsdf__v1__pb2.FileName()
855
+ if commit:
856
+ self.commit()
857
+ else:
858
+ self._stub.Import(self._grpcbsdf)
859
+ if file_path.suffix == ".anisotropicbsdf":
860
+ file_name.file_name = str(file_path)
861
+ else:
862
+ file_name.file_name = str(file_path.parent / (file_path.name + ".anisotropicbsdf"))
863
+ self._stub.Save(file_name)
864
+ return Path(file_name.file_name)
725
865
 
726
- def create_interpolation_enhancement(
727
- self, index_1: float = 1.0, index_2: float = 1.0
728
- ) -> InterpolationEnhancement:
729
- """Apply automatic interpolation enhancement.
730
866
 
731
- Return interpolation settings to user if settings need change.
867
+ class SpectralBRDF(BaseBSDF):
868
+ """BSDF - Bidirectional scattering distribution function.
869
+
870
+ This class contains the methods and functions to load and edit existing Speos bsdf datasets.
871
+
872
+ Parameters
873
+ ----------
874
+ speos : ansys.speos.core.speos.Speos
875
+ Speos Object to connect to speos rpc server
876
+ file_path : Union[Path, str]
877
+ File path to bsdf file
878
+ """
879
+
880
+ def __init__(self, speos: Speos, file_path: Union[Path, str] = None):
881
+ super().__init__(
882
+ speos,
883
+ spectral_bsdf__v1__pb2_grpc.SpectralBsdfServiceStub(speos.client.channel),
884
+ spectral_bsdf__v1__pb2,
885
+ )
886
+ self._spectrum_incidence = [0, 0]
887
+ self._spectrum_anisotropy = [0, 0]
888
+ if file_path:
889
+ file_path = Path(file_path)
890
+ self._grpcbsdf = self._import_file(file_path)
891
+ self.brdf, self.btdf = self._extract_bsdf()
892
+ self._has_transmission = bool(self._btdf)
893
+ self._has_reflection = bool(self._brdf)
894
+ try:
895
+ self._stub.GetSpecularInterpolationEnhancementData(Empty())
896
+ self._BaseBSDF__interpolation_settings = InterpolationEnhancement(
897
+ bsdf=self,
898
+ bsdf_namespace=spectral_bsdf__v1__pb2,
899
+ index_1=None,
900
+ index_2=None,
901
+ )
902
+ except grpc.RpcError:
903
+ self.__interpolation_settings = None
904
+ else:
905
+ self._transmission_spectrum, self._reflection_spectrum = None, None
906
+
907
+ @property
908
+ def wavelength(self):
909
+ """List of all Wavelength in BRDF."""
910
+ r_wl = []
911
+ t_wl = []
912
+ if self.has_reflection:
913
+ for brdf in self.brdf:
914
+ r_wl.append(brdf.wavelength)
915
+ return list(set(r_wl))
916
+ if self.has_transmission:
917
+ for btdf in self.btdf:
918
+ t_wl.append(btdf.wavelength)
919
+ return list(set(t_wl))
920
+ else:
921
+ return []
922
+
923
+ def get(self, key=""):
924
+ """Retrieve any information from the BSDF object.
732
925
 
733
926
  Parameters
734
927
  ----------
735
- index_1 : float
736
- outside refractive index
737
- index_2 : float
738
- inside refractive index
928
+ key : str
929
+ Name of the property.
739
930
 
740
931
  Returns
741
932
  -------
742
- ansys.speos.core.bsdf._InterpolationEnhancement
743
- automatic interpolation settings with index_1 = 1 and index_2 = 1 by default.
933
+ property
934
+ Values/content of the associated property.
744
935
  """
745
- self._stub.Import(self._grpcbsdf)
746
- self.__interpolation_settings = InterpolationEnhancement(
747
- bsdf=self, bsdf_namespace=anisotropic_bsdf__v1__pb2, index_1=index_1, index_2=index_2
936
+ data = {k: v.fget(self) for k, v in BaseBSDF.__dict__.items() if isinstance(v, property)}
937
+ data.update(
938
+ {k: v.fget(self) for k, v in SpectralBRDF.__dict__.items() if isinstance(v, property)}
748
939
  )
749
- return self.__interpolation_settings
940
+ if key == "":
941
+ return data
942
+ elif data.get(key):
943
+ return data.get(key)
944
+ else:
945
+ print("Used key: {} not found in key list: {}.".format(key, data.keys()))
946
+
947
+ def __str__(self):
948
+ """Create string representation of a BSDF."""
949
+ return str(self.get())
950
+
951
+ def _import_file(self, filepath):
952
+ file_name = spectral_bsdf__v1__pb2.FileName()
953
+ file_name.file_name = str(filepath)
954
+ self._stub.Load(file_name)
955
+ return self._stub.Export(Empty())
956
+
957
+ def _extract_bsdf(self) -> tuple[list[BxdfDatapoint], list[BxdfDatapoint]]:
958
+ self.description = self._grpcbsdf.description
959
+ brdf = []
960
+ btdf = []
961
+ for i, spectral_bsdf_data in enumerate(self._grpcbsdf.wavelength_incidence_samples):
962
+ anisotropic_angle = 0
963
+ incident_angle = self._grpcbsdf.incidence_samples[
964
+ i % len(self._grpcbsdf.incidence_samples)
965
+ ]
966
+ wl = self._grpcbsdf.wavelength_samples[int(i / len(self._grpcbsdf.incidence_samples))]
967
+ if spectral_bsdf_data.HasField("reflection"):
968
+ thetas = np.array(spectral_bsdf_data.reflection.theta_samples)
969
+ phis = np.array(spectral_bsdf_data.reflection.phi_samples)
970
+ bsdf = np.array(spectral_bsdf_data.reflection.bsdf_cos_theta).reshape(
971
+ (len(thetas), len(phis))
972
+ )
973
+ tis = spectral_bsdf_data.reflection.integral
974
+ brdf.append(
975
+ BxdfDatapoint(
976
+ True, incident_angle, thetas, phis, bsdf, tis, anisotropic_angle, wl
977
+ )
978
+ )
979
+ if spectral_bsdf_data.HasField("transmission"):
980
+ thetas = np.array(spectral_bsdf_data.transmission.theta_samples)
981
+ phis = np.array(spectral_bsdf_data.transmission.phi_samples)
982
+ bsdf = np.array(spectral_bsdf_data.transmission.bsdf_cos_theta).reshape(
983
+ (len(thetas), len(phis))
984
+ )
985
+ tis = spectral_bsdf_data.transmission.integral
986
+ btdf.append(
987
+ BxdfDatapoint(
988
+ False, incident_angle, thetas, phis, bsdf, tis, anisotropic_angle, wl
989
+ )
990
+ )
991
+ if not brdf:
992
+ brdf = None
993
+ if not btdf:
994
+ btdf = None
995
+ return brdf, btdf
996
+
997
+ def reset(self):
998
+ """Reset BSDF data to what was stored in file."""
999
+ self._brdf, self._btdf = self._extract_bsdf()
1000
+ self._has_transmission = bool(self._btdf)
1001
+ self._has_reflection = bool(self._brdf)
1002
+
1003
+ def sanity_check(self, silent: bool = True) -> str:
1004
+ """Verify BSDF data is correctly defined.
1005
+
1006
+ Parameters
1007
+ ----------
1008
+ silent : bool
1009
+ If False Warnings will be raised else not, by Default True
1010
+
1011
+ Returns
1012
+ -------
1013
+ WarningInformation : str
1014
+ Description of what data is missing or incorrect
1015
+ """
1016
+ return self._sanity_check(raise_error=False, silent=silent)
1017
+
1018
+ def _sanity_check(self, raise_error=False, silent=True):
1019
+ """Validate data.
1020
+
1021
+ Allow to raise an error
1022
+ """
1023
+ r_wl = []
1024
+ r_inc = []
1025
+ t_wl = []
1026
+ t_inc = []
1027
+ error_msg = ""
1028
+ match self.has_reflection, self.has_transmission:
1029
+ case True, True:
1030
+ for brdf, btdf in zip(self.brdf, self.btdf):
1031
+ r_inc.append(brdf.incident_angle)
1032
+ r_wl.append(brdf.wavelength)
1033
+ t_inc.append(btdf.incident_angle)
1034
+ t_wl.append(btdf.wavelength)
1035
+ if r_inc != t_inc or r_wl != t_wl:
1036
+ error_msg += (
1037
+ "Incidence and/or Wavelength information between reflection and"
1038
+ " transmission is not identical. "
1039
+ )
1040
+ test_inc = r_inc
1041
+ test_wl = r_wl
1042
+ case True, False:
1043
+ for brdf in self.brdf:
1044
+ r_inc.append(brdf.incident_angle)
1045
+ r_wl.append(brdf.wavelength)
1046
+ test_inc = r_inc
1047
+ test_wl = r_wl
1048
+ case False, True:
1049
+ for btdf in self.btdf:
1050
+ t_inc.append(btdf.incident_angle)
1051
+ t_wl.append(btdf.wavelength)
1052
+ test_inc = t_inc
1053
+ test_wl = t_wl
1054
+ case _:
1055
+ test_inc = []
1056
+ test_wl = []
1057
+ inc_f = dict(Counter(test_inc))
1058
+ wl_f = dict(Counter(test_wl))
1059
+ inc_error_l = []
1060
+ wl_error_l = []
1061
+ for key in inc_f:
1062
+ if len(wl_f.keys()) != inc_f[key]:
1063
+ inc_error_l.append(key)
1064
+ for key in wl_f:
1065
+ if len(inc_f.keys()) != wl_f[key]:
1066
+ wl_error_l.append(key)
1067
+ if inc_error_l:
1068
+ error_msg += (
1069
+ "The bsdf is missing information's for the for the following incidence"
1070
+ " angles one or more wavelengths are missing: {}. ".format(inc_error_l)
1071
+ )
1072
+ if inc_error_l:
1073
+ error_msg += (
1074
+ "The bsdf is missing information's for the for the following wavelength"
1075
+ " one or more incidence angles are missing: {}. ".format(wl_error_l)
1076
+ )
1077
+ if raise_error:
1078
+ if error_msg:
1079
+ raise ValueError(error_msg)
1080
+ elif silent:
1081
+ return error_msg
1082
+ else:
1083
+ if error_msg:
1084
+ warnings.warn(error_msg, stacklevel=2)
1085
+ return error_msg
1086
+
1087
+ def commit(self):
1088
+ """Sent Data to gRPC interface."""
1089
+ # set basic values
1090
+ self._sanity_check(raise_error=True)
1091
+ spectral_bsdf = spectral_bsdf__v1__pb2.SpectralBsdfData()
1092
+ spectral_bsdf.description = self.description
1093
+ wl = []
1094
+ inc = []
1095
+ match self.has_reflection, self.has_transmission:
1096
+ case True, True:
1097
+ for brdf, btdf in zip(self.brdf, self.btdf):
1098
+ inc.append(brdf.incident_angle)
1099
+ wl.append(brdf.wavelength)
1100
+ iw = spectral_bsdf.wavelength_incidence_samples.add()
1101
+ iw.reflection.integral = brdf.tis
1102
+ iw.reflection.phi_samples[:] = list(brdf.phi_values)
1103
+ iw.reflection.theta_samples[:] = list(brdf.theta_values)
1104
+ iw.reflection.bsdf_cos_theta[:] = brdf.bxdf.flatten().tolist()
1105
+ iw.transmission.integral = btdf.tis
1106
+ iw.transmission.phi_samples[:] = list(btdf.phi_values)
1107
+ iw.transmission.theta_samples[:] = list(btdf.theta_values)
1108
+ iw.transmission.bsdf_cos_theta[:] = btdf.bxdf.flatten().tolist()
1109
+ case True, False:
1110
+ for brdf in self.brdf:
1111
+ inc.append(brdf.incident_angle)
1112
+ wl.append(brdf.wavelength)
1113
+ iw = spectral_bsdf.wavelength_incidence_samples.add()
1114
+ iw.reflection.integral = brdf.tis
1115
+ iw.reflection.phi_samples[:] = list(brdf.phi_values)
1116
+ iw.reflection.theta_samples[:] = list(brdf.theta_values)
1117
+ iw.reflection.bsdf_cos_theta[:] = brdf.bxdf.flatten().tolist()
1118
+ case False, True:
1119
+ for btdf in self.btdf:
1120
+ inc.append(btdf.incident_angle)
1121
+ wl.append(btdf.wavelength)
1122
+ iw = spectral_bsdf.wavelength_incidence_samples.add()
1123
+ iw.transmission.integral = btdf.tis
1124
+ iw.transmission.phi_samples[:] = list(btdf.phi_values)
1125
+ iw.transmission.theta_samples[:] = list(btdf.theta_values)
1126
+ iw.transmission.bsdf_cos_theta[:] = btdf.bxdf.flatten().tolist()
1127
+ inc = list(set(inc))
1128
+ wl = list(set(wl))
1129
+ inc.sort()
1130
+ wl.sort()
1131
+ spectral_bsdf.incidence_samples[:] = inc
1132
+ spectral_bsdf.wavelength_samples[:] = wl
1133
+ self._stub.Import(spectral_bsdf)
1134
+ self._grpcbsdf = spectral_bsdf
1135
+ if self._BaseBSDF__interpolation_settings is not None:
1136
+ self._stub.SetSpecularInterpolationEnhancementData(
1137
+ self._BaseBSDF__interpolation_settings._InterpolationEnhancement__cones_data
1138
+ )
750
1139
 
751
1140
  def save(self, file_path: Union[Path, str], commit: bool = True) -> Path:
752
1141
  """Save a Speos anistropic bsdf.
@@ -764,17 +1153,17 @@ class AnisotropicBSDF(BaseBSDF):
764
1153
  File location
765
1154
  """
766
1155
  file_path = Path(file_path)
767
- file_name = anisotropic_bsdf__v1__pb2.FileName()
1156
+ file_name = spectral_bsdf__v1__pb2.FileName()
768
1157
  if commit:
769
1158
  self.commit()
770
1159
  else:
771
1160
  self._stub.Import(self._grpcbsdf)
772
- if file_path.suffix == ".anisotropicbsdf":
1161
+ if file_path.suffix == ".brdf":
773
1162
  file_name.file_name = str(file_path)
774
1163
  else:
775
- file_name.file_name = str(file_path.parent / (file_path.name + ".anisotropicbsdf"))
1164
+ file_name.file_name = str(file_path.parent / (file_path.name + ".brdf"))
776
1165
  self._stub.Save(file_name)
777
- return file_name.file_name
1166
+ return Path(file_name.file_name)
778
1167
 
779
1168
 
780
1169
  class BxdfDatapoint:
@@ -794,6 +1183,8 @@ class BxdfDatapoint:
794
1183
  nested list of bxdf values in 1/sr
795
1184
  anisotropy : float
796
1185
  Anisotropy angle in radian
1186
+ wavelength : float
1187
+ Wavelength in nm
797
1188
  """
798
1189
 
799
1190
  def __init__(
@@ -792,7 +792,8 @@ class BaseSensor:
792
792
  ansys.speos.core.sensor.BaseSensor
793
793
  Sensor feature.
794
794
  """
795
- self._visual_data.updated = False
795
+ if general_methods._GRAPHICS_AVAILABLE:
796
+ self._visual_data.updated = False
796
797
 
797
798
  # The _unique_id will help to find the correct item in the scene.sensors:
798
799
  # the list of SensorInstance
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ansys-speos-core
3
- Version: 0.5.1
3
+ Version: 0.5.2
4
4
  Summary: A Python wrapper for Ansys Speos
5
5
  Author-email: "ANSYS, Inc." <pyansys.core@ansys.com>
6
6
  Maintainer-email: "ANSYS, Inc." <pyansys.core@ansys.com>
@@ -1,6 +1,6 @@
1
1
  ansys/speos/core/__init__.py,sha256=IVbIofkDu5EBe1sOr5SYfISacoR4gkb8sm2S-hFbXmw,2173
2
2
  ansys/speos/core/body.py,sha256=Y-IkhdTksca3FVeztZIZLb8lzYVbYLdc_bMhKH-wkpI,8530
3
- ansys/speos/core/bsdf.py,sha256=1kEFLQP8F5sU24aWCDjD4Oyu4YGfu3abmsvkoJgRbz0,44782
3
+ ansys/speos/core/bsdf.py,sha256=h-33-00sKXTXdWvtcexqEL4i4S4gtMDHzF-AR1_i7HU,61522
4
4
  ansys/speos/core/face.py,sha256=PaywEiEO-gt96PVzrm46rba4DrqPFPxyNajNwB4ZPn8,7234
5
5
  ansys/speos/core/geo_ref.py,sha256=zBvCepLSslR_Kr8x51eDK2_ShVj0Tu1AZA2aOfPWqjY,2057
6
6
  ansys/speos/core/intensity.py,sha256=DJ3lLQyQWQoFxD1_bl5K286nHnOcu5yh4bTiWR-BsVs,17638
@@ -12,7 +12,7 @@ ansys/speos/core/part.py,sha256=upi3zXtergps4B8QsNUnOE2v9MYBWvciP2ewnW7FfeE,2408
12
12
  ansys/speos/core/project.py,sha256=Di9BAOoR_TftzrMiassgZaFSFnD_WIwXg4unFxK5NWE,37170
13
13
  ansys/speos/core/proto_message_utils.py,sha256=eZYcvrSxqFjemQwyXjcVTn_WpiN_3uGUpi_Y8ylddJ0,10285
14
14
  ansys/speos/core/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
- ansys/speos/core/sensor.py,sha256=T-Q4Dyl2kIrBDWW9zFETy5A87IzVLuEO-b17uXQ_nmc,113426
15
+ ansys/speos/core/sensor.py,sha256=BIlOzL4b2m6-8wt48wSl1ALTsCvoT9eFbJMJdmcplZs,113478
16
16
  ansys/speos/core/simulation.py,sha256=1iYJRxlhDI5fewLyztdo6uBH1Hd246kcckrNPpLQG6Y,48331
17
17
  ansys/speos/core/source.py,sha256=uPOuJG89i8GdotiVELGUwUlqxud3VC1PnPF_XxOx46k,37934
18
18
  ansys/speos/core/spectrum.py,sha256=PZpHlZ7nVsYFzFeOg1D49aREkWxHI3Nei1CQ4TrTMKs,9509
@@ -39,7 +39,7 @@ ansys/speos/core/kernel/vop_template.py,sha256=w6p3B-BnKU4k_6KufMUQ4WToxw0SNOVXy
39
39
  ansys/speos/core/workflow/__init__.py,sha256=zaZ2dEvMudGZ98MdVZY0Ej-KHtU6qSULFviE-PuIuGM,1512
40
40
  ansys/speos/core/workflow/combine_speos.py,sha256=alTwsu19RUruVXdtseLia24xMMHy5439OQcAWLirRxI,6380
41
41
  ansys/speos/core/workflow/open_result.py,sha256=8n5OrkBVeanD6zmtNrZ4vMCSaNVWh1PmCGXiPiLiBUE,5566
42
- ansys_speos_core-0.5.1.dist-info/licenses/LICENSE,sha256=IhvStQBsZm7tV9bx9yvmmBXxrigDLUeCP8h8TevNE7k,1098
43
- ansys_speos_core-0.5.1.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
44
- ansys_speos_core-0.5.1.dist-info/METADATA,sha256=hs_0h9ynlArUc4UagaFiiDuG8QA2iCiNOMqvYCGuqcI,10106
45
- ansys_speos_core-0.5.1.dist-info/RECORD,,
42
+ ansys_speos_core-0.5.2.dist-info/licenses/LICENSE,sha256=IhvStQBsZm7tV9bx9yvmmBXxrigDLUeCP8h8TevNE7k,1098
43
+ ansys_speos_core-0.5.2.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
44
+ ansys_speos_core-0.5.2.dist-info/METADATA,sha256=T18HLLSCkRrqtqHRjGHWylyXs_o8bDR4MziRcTiDSJ8,10106
45
+ ansys_speos_core-0.5.2.dist-info/RECORD,,