ClassSegmentationConfigurationComponent.cpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <AzCore/Serialization/EditContext.h>
  9. #include <AzCore/Serialization/SerializeContext.h>
  10. #include <Lidar/ClassSegmentationConfigurationComponent.h>
  11. namespace ROS2Sensors
  12. {
  13. void ClassSegmentationConfigurationComponent::Reflect(AZ::ReflectContext* context)
  14. {
  15. SegmentationClassConfiguration::Reflect(context);
  16. if (auto* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
  17. {
  18. serializeContext->Class<ClassSegmentationConfigurationComponent, AZ::Component>()->Version(0)->Field(
  19. "Segmentation Classes", &ClassSegmentationConfigurationComponent::m_segmentationClasses);
  20. if (auto* editContext = serializeContext->GetEditContext())
  21. {
  22. editContext->Class<ClassSegmentationConfigurationComponent>("Class Segmentation Configuration", "")
  23. ->ClassElement(AZ::Edit::ClassElements::EditorData, "")
  24. ->Attribute(AZ::Edit::Attributes::Category, "ROS2")
  25. ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZStd::vector<AZ::Crc32>({ AZ_CRC_CE("Level") }))
  26. ->DataElement(
  27. AZ::Edit::UIHandlers::Default,
  28. &ClassSegmentationConfigurationComponent::m_segmentationClasses,
  29. "Segmentation classes",
  30. "Segmentation classes and their colors.")
  31. ->Attribute(AZ::Edit::Attributes::AutoExpand, true)
  32. ->Attribute(AZ::Edit::Attributes::ChangeValidate, &ClassSegmentationConfigurationComponent::ValidateSegmentationClasses)
  33. ->Attribute(AZ::Edit::Attributes::ChangeNotify, &ClassSegmentationConfigurationComponent::OnSegmentationClassesChanged);
  34. }
  35. }
  36. }
  37. void ClassSegmentationConfigurationComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
  38. {
  39. provided.push_back(AZ_CRC_CE("ClassSegmentationConfig"));
  40. }
  41. void ClassSegmentationConfigurationComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
  42. {
  43. incompatible.push_back(AZ_CRC_CE("ClassSegmentationConfig"));
  44. }
  45. AZ::Color ClassSegmentationConfigurationComponent::GetClassColor(uint8_t classId) const
  46. {
  47. auto it = m_classIdToColor.find(classId);
  48. if (it == m_classIdToColor.end())
  49. {
  50. return AZ::Colors::White;
  51. }
  52. return it->second;
  53. }
  54. AZStd::optional<uint8_t> ClassSegmentationConfigurationComponent::GetClassIdForTag(LmbrCentral::Tag tag) const
  55. {
  56. auto it = m_tagToClassId.find(tag);
  57. if (it == m_tagToClassId.end())
  58. {
  59. return AZStd::nullopt;
  60. }
  61. return it->second;
  62. }
  63. const SegmentationClassConfigList& ClassSegmentationConfigurationComponent::GetClassConfigList() const
  64. {
  65. return m_segmentationClasses;
  66. }
  67. void ClassSegmentationConfigurationComponent::Activate()
  68. {
  69. ConstructSegmentationClassMaps();
  70. if (!ClassSegmentationInterface::Get())
  71. {
  72. ClassSegmentationInterface::Register(this);
  73. }
  74. }
  75. void ClassSegmentationConfigurationComponent::Deactivate()
  76. {
  77. if (ClassSegmentationInterface::Get() == this)
  78. {
  79. ClassSegmentationInterface::Unregister(this);
  80. }
  81. m_classIdToColor.clear();
  82. m_tagToClassId.clear();
  83. }
  84. AZ::Outcome<void, AZStd::string> ClassSegmentationConfigurationComponent::ValidateSegmentationClasses(
  85. void* newValue, const AZ::TypeId& valueType) const
  86. {
  87. AZ_Assert(azrtti_typeid<SegmentationClassConfigList>() == valueType, "Unexpected value type");
  88. if (azrtti_typeid<SegmentationClassConfigList>() != valueType)
  89. {
  90. return AZ::Failure(AZStd::string("Unexpectedly received an invalid type as segmentation classes!"));
  91. }
  92. const auto& segmentationClasses = *azrtti_cast<SegmentationClassConfigList*>(newValue);
  93. bool unknownPresent{ false }, groundPresent{ false };
  94. for (const auto& segmentationClass : segmentationClasses)
  95. {
  96. if (segmentationClass.m_classId == SegmentationClassConfiguration::UnknownClass.m_classId &&
  97. segmentationClass.m_className == SegmentationClassConfiguration::UnknownClass.m_className)
  98. {
  99. unknownPresent = true;
  100. }
  101. if (segmentationClass.m_classId == SegmentationClassConfiguration::GroundClass.m_classId &&
  102. segmentationClass.m_className == SegmentationClassConfiguration::GroundClass.m_className)
  103. {
  104. groundPresent = true;
  105. }
  106. }
  107. if (!unknownPresent || !groundPresent)
  108. {
  109. return AZ::Failure(
  110. AZStd::string::format("Segmentation class with name %s must exist.", (!unknownPresent ? "Unknown" : "Ground")));
  111. }
  112. return AZ::Success();
  113. }
  114. void ClassSegmentationConfigurationComponent::ConstructSegmentationClassMaps()
  115. {
  116. m_classIdToColor.reserve(m_segmentationClasses.size());
  117. m_tagToClassId.reserve(m_segmentationClasses.size());
  118. for (const auto& segmentationClass : m_segmentationClasses)
  119. {
  120. m_classIdToColor.insert(AZStd::make_pair(segmentationClass.m_classId, segmentationClass.m_classColor));
  121. m_tagToClassId.insert(AZStd::make_pair(LmbrCentral::Tag(segmentationClass.m_className), segmentationClass.m_classId));
  122. }
  123. }
  124. AZ::Crc32 ClassSegmentationConfigurationComponent::OnSegmentationClassesChanged()
  125. {
  126. bool unknownPresent{ false }, groundPresent{ false };
  127. for (auto& segmentationClass : m_segmentationClasses)
  128. {
  129. if (segmentationClass.m_classId == SegmentationClassConfiguration::UnknownClass.m_classId)
  130. {
  131. unknownPresent = true;
  132. }
  133. if (segmentationClass.m_classId == SegmentationClassConfiguration::GroundClass.m_classId)
  134. {
  135. groundPresent = true;
  136. }
  137. }
  138. if (unknownPresent && groundPresent)
  139. {
  140. return AZ::Edit::PropertyRefreshLevels::None;
  141. }
  142. if (!unknownPresent)
  143. {
  144. m_segmentationClasses.push_back(SegmentationClassConfiguration::UnknownClass);
  145. }
  146. if (!groundPresent)
  147. {
  148. m_segmentationClasses.push_back(SegmentationClassConfiguration::GroundClass);
  149. }
  150. return AZ::Edit::PropertyRefreshLevels::EntireTree;
  151. }
  152. } // namespace ROS2Sensors