741{
743 if (!currentNode) {
744 static G4bool first =
true;
745 if (first) {
746 first = false;
747 G4Exception(
"G4Qt3DSceneHandler::AddPrimitive(const G4Polyhedron&)",
749 "No available node!");
750 }
751 return;
752 }
753
755
757
758
759
760
761
762
763
764
765 std::vector<G4Point3D> vertices;
766 std::vector<G4Normal3D> normals;
767
768
769
770 typedef std::pair<G4Point3D,G4Point3D> Line;
771 std::vector<Line> lines;
772 auto insertIfNew = [&lines](const Line& newLine) {
773
774
775
776
777
778
779
780
781 lines.push_back(newLine);
782 };
783
786 do {
791 notLastFace = polyhedron.
GetNextFacet(nEdges, vertex, edgeFlag, normal);
792 vertices.push_back(vertex[0]);
793 vertices.push_back(vertex[1]);
794 vertices.push_back(vertex[2]);
795 normals.push_back(normal[0]);
796 normals.push_back(normal[1]);
797 normals.push_back(normal[2]);
798 if(isAuxilaryEdgeVisible||edgeFlag[0]>0)insertIfNew(Line(vertex[0],vertex[1]));
799 if(isAuxilaryEdgeVisible||edgeFlag[1]>0)insertIfNew(Line(vertex[1],vertex[2]));
800 if (nEdges == 3) {
801
802
803 if(isAuxilaryEdgeVisible||edgeFlag[2]>0)insertIfNew(Line(vertex[2],vertex[0]));
804 } else if (nEdges == 4) {
805
806
807 vertices.push_back(vertex[2]);
808 vertices.push_back(vertex[3]);
809 vertices.push_back(vertex[0]);
810 normals.push_back(normal[2]);
811 normals.push_back(normal[3]);
812 normals.push_back(normal[0]);
813 if(isAuxilaryEdgeVisible||edgeFlag[2]>0)insertIfNew(Line(vertex[2],vertex[3]));
814 if(isAuxilaryEdgeVisible||edgeFlag[3]>0)insertIfNew(Line(vertex[3],vertex[0]));
815 } else {
817 << "ERROR: polyhedron face with unexpected number of edges (" << nEdges << ')'
820 return;
821 }
822 } while (notLastFace);
823 const auto nVerts = vertices.size();
824 const auto nLines = lines.size();
825
826
827
829 transform->setObjectName("transform");
830
831 Qt3DCore::QEntity* wireframeEntity = nullptr;
832 Qt3DCore::QEntity* surfaceEntity = nullptr;
833 static G4int errorCount = 0;
835 switch (drawing_style) {
837 wireframeEntity = new Qt3DCore::QEntity(currentNode);
838 wireframeEntity->addComponent(transform);
839 break;
841 wireframeEntity = new Qt3DCore::QEntity(currentNode);
842 wireframeEntity->addComponent(transform);
843 surfaceEntity = new Qt3DCore::QEntity(currentNode);
844 surfaceEntity->addComponent(transform);
845 break;
847 surfaceEntity = new Qt3DCore::QEntity(currentNode);
848 surfaceEntity->addComponent(transform);
849 break;
851 wireframeEntity = new Qt3DCore::QEntity(currentNode);
852 wireframeEntity->addComponent(transform);
853 surfaceEntity = new Qt3DCore::QEntity(currentNode);
854 surfaceEntity->addComponent(transform);
855 break;
857
858 if (errorCount == 0) {
859 ++errorCount;
860 G4warn <<
"WARNING: Qt3D: cloud drawing not implemented" <<
G4endl;
861 }
862 return;
863 break;
864 }
865
866 const auto vertexByteSize = 3*
sizeof(
PRECISION);
867
868 G4Qt3DCompat::QGeometry* vertexGeometry = nullptr;
869 G4Qt3DCompat::QGeometry* lineGeometry = nullptr;
870
871 G4Qt3DCompat::QAttribute* positionAtt = nullptr;
872 G4Qt3DCompat::QAttribute* normalAtt = nullptr;
873 G4Qt3DCompat::QAttribute* lineAtt = nullptr;
874 G4Qt3DCompat::QAttribute* dummyNormalLineAtt = nullptr;
875
876 G4Qt3DCompat::QBuffer* vertexBuffer = nullptr;
880
881
882
883 QByteArray vertexByteArray;
884 const auto vertexBufferByteSize = 2*nVerts*vertexByteSize;
885 vertexByteArray.resize((
G4int)vertexBufferByteSize);
886 auto vertexBufferArray =
reinterpret_cast<PRECISION*
>(vertexByteArray.data());
888 for (std::size_t i = 0; i < nVerts; ++i) {
889 vertexBufferArray[i1++] = vertices[i].x();
890 vertexBufferArray[i1++] = vertices[i].y();
891 vertexBufferArray[i1++] = vertices[i].z();
892 vertexBufferArray[i1++] = normals[i].x();
893 vertexBufferArray[i1++] = normals[i].y();
894 vertexBufferArray[i1++] = normals[i].z();
895 }
896
897 vertexGeometry = new G4Qt3DCompat::QGeometry();
898 vertexGeometry->setObjectName("vertexGeometry");
899 vertexBuffer = new G4Qt3DCompat::QBuffer(vertexGeometry);
900 vertexBuffer->setObjectName("Vertex buffer");
901 vertexBuffer->setData(vertexByteArray);
902
903
904 positionAtt = new G4Qt3DCompat::QAttribute;
905 positionAtt->setObjectName("Position attribute");
906 positionAtt->setName(G4Qt3DCompat::QAttribute::defaultPositionAttributeName());
907 positionAtt->setBuffer(vertexBuffer);
908 positionAtt->setAttributeType(G4Qt3DCompat::QAttribute::VertexAttribute);
909 positionAtt->setVertexBaseType(
BASETYPE);
910 positionAtt->setVertexSize(3);
911 positionAtt->setCount((
G4int)nVerts);
912 positionAtt->setByteOffset(0);
913 positionAtt->setByteStride(2*vertexByteSize);
914
915
916 normalAtt = new G4Qt3DCompat::QAttribute;
917 normalAtt->setObjectName("Normal attribute");
918 normalAtt->setName(G4Qt3DCompat::QAttribute::defaultNormalAttributeName());
919 normalAtt->setBuffer(vertexBuffer);
920 normalAtt->setAttributeType(G4Qt3DCompat::QAttribute::VertexAttribute);
921 normalAtt->setVertexBaseType(
BASETYPE);
922 normalAtt->setVertexSize(3);
923 normalAtt->setCount((
G4int)nVerts);
924 normalAtt->setByteOffset(vertexByteSize);
925 normalAtt->setByteStride(2*vertexByteSize);
926 }
927
928 G4Qt3DCompat::QBuffer* lineBuffer = nullptr;
932
933
934 QByteArray lineByteArray;
935 const auto lineBufferByteSize = 2*nLines*vertexByteSize;
936 lineByteArray.resize((
G4int)lineBufferByteSize);
937 auto lineBufferArray =
reinterpret_cast<PRECISION*
>(lineByteArray.data());
939 for (const auto& line: lines) {
940 lineBufferArray[i2++] = line.first.x();
941 lineBufferArray[i2++] = line.first.y();
942 lineBufferArray[i2++] = line.first.z();
943 lineBufferArray[i2++] = line.second.x();
944 lineBufferArray[i2++] = line.second.y();
945 lineBufferArray[i2++] = line.second.z();
946 }
947
948 lineGeometry = new G4Qt3DCompat::QGeometry();
949 lineGeometry->setObjectName("lineGeometry");
950 lineBuffer = new G4Qt3DCompat::QBuffer(lineGeometry);
951 lineBuffer->setObjectName("Line buffer");
952 lineBuffer->setData(lineByteArray);
953
954
955 lineAtt = new G4Qt3DCompat::QAttribute;
956 lineAtt->setObjectName("Position attribute");
957 lineAtt->setName(G4Qt3DCompat::QAttribute::defaultPositionAttributeName());
958 lineAtt->setBuffer(lineBuffer);
959 lineAtt->setAttributeType(G4Qt3DCompat::QAttribute::VertexAttribute);
960 lineAtt->setVertexBaseType(
BASETYPE);
961 lineAtt->setVertexSize(3);
962 lineAtt->setCount((
G4int)nLines);
963 lineAtt->setByteOffset(0);
964 lineAtt->setByteStride(vertexByteSize);
965
966 dummyNormalLineAtt = new G4Qt3DCompat::QAttribute;
967 dummyNormalLineAtt->setObjectName("Normal attribute");
968 dummyNormalLineAtt->setName(G4Qt3DCompat::QAttribute::defaultNormalAttributeName());
969 dummyNormalLineAtt->setBuffer(lineBuffer);
970 dummyNormalLineAtt->setAttributeType(G4Qt3DCompat::QAttribute::VertexAttribute);
971 dummyNormalLineAtt->setVertexBaseType(
BASETYPE);
972 dummyNormalLineAtt->setVertexSize(3);
973 dummyNormalLineAtt->setCount(0);
974 dummyNormalLineAtt->setByteOffset(0);
975 dummyNormalLineAtt->setByteStride(vertexByteSize);
976 }
977
978
979
981 Qt3DExtras::QDiffuseSpecularMaterial* material;
982 Qt3DRender::QGeometryRenderer* renderer;
983 switch (drawing_style) {
984
986
987 lineGeometry->addAttribute(lineAtt);
988 lineGeometry->addAttribute(dummyNormalLineAtt);
989
990 material = new Qt3DExtras::QDiffuseSpecularMaterial();
991 material->setObjectName("materialForWireframe");
993 material->setShininess(0.);
994 material->setSpecular(0.);
995 wireframeEntity->addComponent(material);
996
997 renderer = new Qt3DRender::QGeometryRenderer;
998 renderer->setObjectName("polyhedronWireframeRenderer");
999 renderer->setGeometry(lineGeometry);
1000 renderer->setVertexCount(2*(
G4int)nLines);
1001 renderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::Lines);
1002 wireframeEntity->addComponent(renderer);
1003
1004 break;
1005
1007
1008
1009
1010 vertexGeometry->addAttribute(positionAtt);
1011 vertexGeometry->addAttribute(normalAtt);
1012
1013 material = new Qt3DExtras::QDiffuseSpecularMaterial();
1014 material->setObjectName("materialForHiddenLines");
1015 material->setAmbient(Qt::white);
1016 material->setShininess(0.);
1017 material->setSpecular(0.);
1018 surfaceEntity->addComponent(material);
1019
1020 renderer = new Qt3DRender::QGeometryRenderer;
1021 renderer->setObjectName("polyhedronSurfaceRenderer");
1022 renderer->setGeometry(vertexGeometry);
1023 renderer->setVertexCount((
G4int)nVerts);
1024 renderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::Triangles);
1025 surfaceEntity->addComponent(renderer);
1026
1027
1028
1029 lineGeometry->addAttribute(lineAtt);
1030 lineGeometry->addAttribute(dummyNormalLineAtt);
1031
1032 material = new Qt3DExtras::QDiffuseSpecularMaterial();
1033 material->setObjectName("materialForWireFrame");
1035 material->setShininess(0.);
1036 material->setSpecular(0.);
1037 wireframeEntity->addComponent(material);
1038
1039 renderer = new Qt3DRender::QGeometryRenderer;
1040 renderer->setObjectName("polyhedronWireframeRenderer");
1041 renderer->setGeometry(lineGeometry);
1042 renderer->setVertexCount(2*(
G4int)nLines);
1043 renderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::Lines);
1044 wireframeEntity->addComponent(renderer);
1045
1046 break;
1047
1049
1050 vertexGeometry->addAttribute(positionAtt);
1051 vertexGeometry->addAttribute(normalAtt);
1052
1053 material = new Qt3DExtras::QDiffuseSpecularMaterial();
1054 material->setObjectName("materialForSurface");
1056 if (colour.GetAlpha() < 1.) material->setAlphaBlendingEnabled(true);
1057 surfaceEntity->addComponent(material);
1058
1059 renderer = new Qt3DRender::QGeometryRenderer;
1060 renderer->setObjectName("polyhedronSurfaceRenderer");
1061 renderer->setGeometry(vertexGeometry);
1062 renderer->setVertexCount((
G4int)nVerts);
1063 renderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::Triangles);
1064 surfaceEntity->addComponent(renderer);
1065
1066 break;
1067
1069
1070
1071
1072 vertexGeometry->addAttribute(positionAtt);
1073 vertexGeometry->addAttribute(normalAtt);
1074
1075 material = new Qt3DExtras::QDiffuseSpecularMaterial();
1076 material->setObjectName("materialForSurface");
1078 if (colour.GetAlpha() < 1.) material->setAlphaBlendingEnabled(true);
1079 surfaceEntity->addComponent(material);
1080
1081 renderer = new Qt3DRender::QGeometryRenderer;
1082 renderer->setObjectName("polyhedronSurfaceRenderer");
1083 renderer->setGeometry(vertexGeometry);
1084 renderer->setVertexCount((
G4int)nVerts);
1085 renderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::Triangles);
1086 surfaceEntity->addComponent(renderer);
1087
1088
1089
1090 lineGeometry->addAttribute(lineAtt);
1091 lineGeometry->addAttribute(dummyNormalLineAtt);
1092
1093 material = new Qt3DExtras::QDiffuseSpecularMaterial();
1094 material->setObjectName("materialForWireframe");
1096 material->setShininess(0.);
1097 material->setSpecular(0.);
1098 wireframeEntity->addComponent(material);
1099
1100 renderer = new Qt3DRender::QGeometryRenderer;
1101 renderer->setObjectName("polyhedronSurfaceRenderer");
1102 renderer->setGeometry(lineGeometry);
1103 renderer->setVertexCount(2*(
G4int)nLines);
1104 renderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::Lines);
1105 wireframeEntity->addComponent(renderer);
1106
1107 break;
1108
1110
1111 break;
1112 }
1113}
virtual G4String GetCurrentTag() const
G4ViewParameters::DrawingStyle GetDrawingStyle(const G4VisAttributes *)
const G4ViewParameters & GetViewParameters() const
G4bool IsAuxEdgeVisible() const
G4int GetNoFacets() const
G4bool GetNextFacet(G4int &n, G4Point3D *nodes, G4int *edgeFlags=nullptr, G4Normal3D *normals=nullptr) const