FreeCAD

Форк
0
/
FeatureMeshSegmentByMesh.cpp 
161 строка · 5.9 Кб
1
/***************************************************************************
2
 *   Copyright (c) 2005 Werner Mayer <wmayer[at]users.sourceforge.net>     *
3
 *                                                                         *
4
 *   This file is part of the FreeCAD CAx development system.              *
5
 *                                                                         *
6
 *   This library is free software; you can redistribute it and/or         *
7
 *   modify it under the terms of the GNU Library General Public           *
8
 *   License as published by the Free Software Foundation; either          *
9
 *   version 2 of the License, or (at your option) any later version.      *
10
 *                                                                         *
11
 *   This library  is distributed in the hope that it will be useful,      *
12
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
14
 *   GNU Library General Public License for more details.                  *
15
 *                                                                         *
16
 *   You should have received a copy of the GNU Library General Public     *
17
 *   License along with this library; see the file COPYING.LIB. If not,    *
18
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
19
 *   Suite 330, Boston, MA  02111-1307, USA                                *
20
 *                                                                         *
21
 ***************************************************************************/
22

23
#include "PreCompiled.h"
24

25
#include <Base/Converter.h>
26

27
#include "Core/Algorithm.h"
28
#include "Core/Evaluation.h"
29

30
#include "FeatureMeshSegmentByMesh.h"
31

32

33
using namespace Mesh;
34
using namespace MeshCore;
35

36
PROPERTY_SOURCE(Mesh::SegmentByMesh, Mesh::Feature)
37

38

39
SegmentByMesh::SegmentByMesh()
40
{
41
    ADD_PROPERTY(Source, (nullptr));
42
    ADD_PROPERTY(Tool, (nullptr));
43
    ADD_PROPERTY(Base, (0.0, 0.0, 0.0));
44
    ADD_PROPERTY(Normal, (0.0, 0.0, 1.0));
45
}
46

47
short SegmentByMesh::mustExecute() const
48
{
49
    if (Source.isTouched() || Tool.isTouched()) {
50
        return 1;
51
    }
52
    if (Source.getValue() && Source.getValue()->isTouched()) {
53
        return 1;
54
    }
55
    if (Tool.getValue() && Tool.getValue()->isTouched()) {
56
        return 1;
57
    }
58
    return 0;
59
}
60

61
App::DocumentObjectExecReturn* SegmentByMesh::execute()
62
{
63
    Mesh::PropertyMeshKernel* kernel = nullptr;
64
    App::DocumentObject* mesh = Source.getValue();
65
    if (mesh) {
66
        App::Property* prop = mesh->getPropertyByName("Mesh");
67
        if (prop && prop->is<Mesh::PropertyMeshKernel>()) {
68
            kernel = static_cast<Mesh::PropertyMeshKernel*>(prop);
69
        }
70
    }
71
    if (!kernel) {
72
        return new App::DocumentObjectExecReturn("No mesh specified.\n");
73
    }
74
    else if (mesh->isError()) {
75
        return new App::DocumentObjectExecReturn("No valid mesh.\n");
76
    }
77

78
    Mesh::PropertyMeshKernel* toolmesh = nullptr;
79
    App::DocumentObject* tool = Tool.getValue();
80
    if (tool) {
81
        App::Property* prop = tool->getPropertyByName("Mesh");
82
        if (prop && prop->is<Mesh::PropertyMeshKernel>()) {
83
            toolmesh = static_cast<Mesh::PropertyMeshKernel*>(prop);
84
        }
85
    }
86
    if (!toolmesh) {
87
        return new App::DocumentObjectExecReturn("No toolmesh specified.\n");
88
    }
89
    else if (tool->isError()) {
90
        return new App::DocumentObjectExecReturn("No valid toolmesh.\n");
91
    }
92

93
    // the clipping plane
94
    Base::Vector3f cBase, cNormal;
95
    cBase = Base::convertTo<Base::Vector3f>(Base.getValue());
96
    cNormal = Base::convertTo<Base::Vector3f>(Normal.getValue());
97

98

99
    const MeshKernel& rMeshKernel = kernel->getValue().getKernel();
100
    const MeshKernel& rToolMesh = toolmesh->getValue().getKernel();
101

102
    // check if the toolmesh is a solid
103
    if (!MeshEvalSolid(rToolMesh).Evaluate()) {
104
        return new App::DocumentObjectExecReturn("Toolmesh is not solid.\n");
105
    }
106

107
    std::vector<MeshCore::FacetIndex> faces;
108
    std::vector<MeshGeomFacet> aFaces;
109

110
    MeshAlgorithm cAlg(rMeshKernel);
111
    if (cNormal.Length() > 0.1f) {  // not a null vector
112
        cAlg.GetFacetsFromToolMesh(rToolMesh, cNormal, faces);
113
    }
114
    else {
115
        cAlg.GetFacetsFromToolMesh(rToolMesh, Base::Vector3f(0.0, 1.0f, 0.0f), faces);
116
    }
117

118
    // if the clipping plane was set then we want only the visible facets
119
    if (cNormal.Length() > 0.1f) {  // not a null vector
120
        // now we have too many facets since we have (invisible) facets near to the back clipping
121
        // plane, so we need the nearest facet to the front clipping plane
122
        //
123
        float fDist = FLOAT_MAX;
124
        MeshCore::FacetIndex uIdx = MeshCore::FACET_INDEX_MAX;
125
        MeshFacetIterator cFIt(rMeshKernel);
126

127
        // get the nearest facet to the user (front clipping plane)
128
        for (MeshCore::FacetIndex it : faces) {
129
            cFIt.Set(it);
130
            float dist = (float)fabs(cFIt->GetGravityPoint().DistanceToPlane(cBase, cNormal));
131
            if (dist < fDist) {
132
                fDist = dist;
133
                uIdx = it;
134
            }
135
        }
136

137
        // succeeded
138
        if (uIdx != MeshCore::FACET_INDEX_MAX) {
139
            // set VISIT-Flag to all outer facets
140
            cAlg.SetFacetFlag(MeshFacet::VISIT);
141
            cAlg.ResetFacetsFlag(faces, MeshFacet::VISIT);
142

143
            faces.clear();
144
            MeshTopFacetVisitor clVisitor(faces);
145
            rMeshKernel.VisitNeighbourFacets(clVisitor, uIdx);
146

147
            // append also the start facet
148
            faces.push_back(uIdx);
149
        }
150
    }
151

152
    for (MeshCore::FacetIndex it : faces) {
153
        aFaces.push_back(rMeshKernel.GetFacet(it));
154
    }
155

156
    std::unique_ptr<MeshObject> pcKernel(new MeshObject);
157
    pcKernel->addFacets(aFaces);
158
    Mesh.setValuePtr(pcKernel.release());
159

160
    return App::DocumentObject::StdReturn;
161
}
162

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.