Skip to content

Commit f6c2d6f

Browse files
chaterpaulADO Sync
andauthored
Sync changes from v24-0-2 (#9)
Co-authored-by: ADO Sync <ado-sync@bentley.com>
1 parent 29504f5 commit f6c2d6f

257 files changed

Lines changed: 15180 additions & 33110 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/CODEOWNERS.txt

Lines changed: 0 additions & 40 deletions
This file was deleted.

InternalAPI/CallbackHelper.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,15 @@
123123
throw std::runtime_error("Set too many Callbacks!"); \
124124
}
125125

126+
#define MAX_CALLBACK_COUNT_20 20
127+
#define DEFINE_FN_POINTER_CALLBACKS_20(X) \
128+
switch (index) \
129+
{ \
130+
X(0) X(1) X(2) X(3) X(4) X(5) X(6) X(7) X(8) X(9) X(10) X(11) X(12) X(13) X(14) X(15) X(16) X(17) X(18) X(19) \
131+
default: \
132+
throw std::runtime_error("Set too many Callbacks!"); \
133+
}
134+
126135

127136
template <typename T1, typename T2>
128137
int GetCallbackIndex(T1 callbackPtrs[], T2 callbackFuncs[], std::string callbackIDs[], T2 & fn, const std::string & fnID, int maxCallbackCount)

InternalAPI/MSPyBindTemplates.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ py::class_<TypeWrapper<T>> bind_TypeWrapper(py::handle scope, std::string const&
3636
typedef TypeWrapper<int> IntWrapper;
3737
typedef TypeWrapper<double> DoubleWrapper;
3838
typedef TypeWrapper<bool> BoolWrapper;
39+
typedef TypeWrapper<MSElementDescrP> MSElementDescrReceiver;
40+
typedef TypeWrapper<DgnModelStatus> DgnModelStatusWrapper;
41+
typedef TypeWrapper<ParameterStatus> ParameterStatusWrapper;
3942

4043
// template<typename T> struct ValueSizeSize
4144
template <typename ValueType, typename holder_type = std::unique_ptr< ValueSizeSize<ValueType> >, typename... Args>

InternalAPI/MSPyCommon.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,17 @@
2424
#define __DOC7(n1, n2, n3, n4, n5, n6, n7) __doc_##n1##_##n2##_##n3##_##n4##_##n5##_##n6##_##n7
2525
#define DOC(...) __EXPAND(__EXPAND(__CAT2(__DOC, __VA_SIZE(__VA_ARGS__)))(__VA_ARGS__))
2626

27+
// Custom deleter for py holder
28+
struct mspydelete {
29+
void operator()(RefCountedBase* p)
30+
{
31+
if (nullptr != p && 0 == p->Release())
32+
{
33+
p = nullptr;
34+
}
35+
}
36+
};
37+
2738

2839
// Opaque types of bvector
2940
#define DEFINE_BVECTOR_TYPE(ValueT, ArrayT) typedef bvector<ValueT> ArrayT; PYBIND11_MAKE_OPAQUE(ArrayT)
@@ -204,4 +215,3 @@ py::class_<bvector<ValueType>, holder_type> bind_PointerVector(py::handle scope,
204215

205216
return cls;
206217
}
207-

InternalAPI/MSPythonEngine.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,4 +162,34 @@ struct ScopeMapManager
162162

163163
};
164164

165+
//=======================================================================================
166+
// @bsiclass 09/23
167+
//=======================================================================================
168+
struct PyNameSpaceManager
169+
{
170+
//WIP: need to add all namespace ID
171+
public: enum NameSpaceID
172+
{
173+
Bentley_Geometry,
174+
Bentley_DgnPlatform,
175+
Bentley_DgnPlatform_Raster,
176+
Bentley_GeoCoordinates,
177+
};
178+
179+
typedef PyNameSpaceManager::NameSpaceID PyNameSpaceID;
180+
181+
private:
182+
static bvector<PyNameSpaceID> m_namespaceIDArray;
183+
184+
public:
185+
186+
MSPYTHONDLL_EXPORT static StatusInt UsingNameSpace(PyNameSpaceID namespaceID);
187+
MSPYTHONDLL_EXPORT static bool IsNameSpaceUsing(PyNameSpaceID namespaceID);
188+
MSPYTHONDLL_EXPORT static StatusInt DelNameSpaceUsing(PyNameSpaceID namespaceID);
189+
MSPYTHONDLL_EXPORT static void ClearNameSpaceUsing();
190+
MSPYTHONDLL_EXPORT static void SetDefaultNameSpaceList();
191+
192+
MSPYTHONDLL_EXPORT static bool IsRegisteredInPython(AStringCR attrName);
193+
};
194+
165195
END_BENTLEY_MSTNPLATFORM_MSPYTHON_NAMESPACE

InternalAPI/OpqueTypes_DgnPlatform.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,18 @@ DEFINE_BVECTOR_TYPE(DgnRasterP, DgnRasterVector);
1818
DEFINE_BVECTOR_TYPE(DgnPlatform::GeoreferencePriority, GeoreferencePriorityVector);
1919

2020
DEFINE_BVECTOR_TYPE(DgnECInstancePtr, DgnECInstanceVector);
21-
DEFINE_BVECTOR_TYPE(DgnTagDefinition, DgnTagDefinitionArray);
21+
DEFINE_BVECTOR_TYPE(DgnTagDefinition, DgnTagDefinitionArray);
22+
23+
DEFINE_BVECTOR_TYPE(MaterialCP, MaterialList);
24+
25+
DEFINE_BMAP_TYPE(MaterialMap::MapType, MaterialMapPtr, MaterialMapPtrList);
26+
27+
DEFINE_BVECTOR_TYPE(DgnFileP, DgnFiles);
28+
29+
DEFINE_BVECTOR_TYPE(IDgnECChangeListenerP, DgnECChangeListeners);
30+
31+
DEFINE_BVECTOR_TYPE(DgnInstanceChangeRecordP, DgnInstanceChangeRecords);
32+
33+
DEFINE_BVECTOR_TYPE(DgnRelationChangeRecordP, DgnRelationChangeRecords);
34+
35+
DEFINE_BVECTOR_TYPE(SheetSizeDefinition, SheetSizeDefinitionVector);

MSPythonCore/ScriptEngineManager/source/MSPythonEngine.cpp

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -793,6 +793,31 @@ void PythonScriptEngine::exec(WCharCP stms, WCharCP funcName, ScriptContext* glo
793793

794794
}
795795

796+
/*---------------------------------------------------------------------------------**//***
797+
@bsimethod 12/2024
798+
+---------------+---------------+---------------+---------------+---------------+------*/
799+
static void getCachedTypes(std::unordered_map<std::type_index, std::string>& before_type_cache)
800+
{
801+
auto& internals = py::detail::get_internals();
802+
for (const auto& item : internals.registered_types_cpp)
803+
before_type_cache[item.first] = item.second->type->tp_name;
804+
}
805+
806+
/*---------------------------------------------------------------------------------**//***
807+
@bsimethod 12/2024
808+
+---------------+---------------+---------------+---------------+---------------+------*/
809+
static void removeCachedtypes(const std::unordered_map<std::type_index, std::string>& before_type_cache)
810+
{
811+
auto& internals = py::detail::get_internals();
812+
for (auto it = internals.registered_types_cpp.begin(); it != internals.registered_types_cpp.end();)
813+
{
814+
if (before_type_cache.find(it->first) == before_type_cache.end())
815+
it = internals.registered_types_cpp.erase(it);
816+
else
817+
++it;
818+
}
819+
}
820+
796821
/*---------------------------------------------------------------------------------**//***
797822
@bsimethod 2/2023
798823
+---------------+---------------+---------------+---------------+---------------+------*/
@@ -826,21 +851,27 @@ void PythonScriptEngine::eval_file(WCharCP scriptFile, WCharCP funcName, ScriptC
826851
localDict = pyLocalDict->m_dict;
827852

828853
m_engineProcessing = true;
854+
855+
// The cache of types registered by pybind11 before running the script
856+
std::unordered_map<std::type_index, std::string> before_type_cache;
857+
getCachedTypes(before_type_cache);
858+
829859
// User want to run a file directly
830860
if (strFileOrModule.EndsWithI(L".py"))
831861
{
832-
// Run file
833862
try
834863
{
835-
// Python returns errors if the local dictionary is empty
864+
// Run file, Python returns errors if the local dictionary is empty
836865
py::eval_file(py::cast(scriptFile), globalDict, py::len(localDict) > 0 ? localDict : py::object ());
837866
}
838867
catch (py::error_already_set& e)
839868
{
869+
removeCachedtypes(before_type_cache);
840870
ScriptEngineManager::Get().InjectError( e.what ());
841871
}
842872
catch (std::exception& err)
843873
{
874+
removeCachedtypes(before_type_cache);
844875
ScriptEngineManager::Get().InjectException(err);
845876
}
846877
}
@@ -870,6 +901,7 @@ void PythonScriptEngine::eval_file(WCharCP scriptFile, WCharCP funcName, ScriptC
870901
}
871902
catch (std::exception& err)
872903
{
904+
removeCachedtypes(before_type_cache);
873905
ScriptEngineManager::Get().InjectException(err);
874906
}
875907
}
@@ -1017,6 +1049,38 @@ void PythonScriptEngine::InitSearchPath ()
10171049
UsingNameSpace(PyNameSpaceManager::Bentley_DgnPlatform_Raster);
10181050
}
10191051

1052+
/*---------------------------------------------------------------------------------**//***
1053+
@bsimethod Chris Wu 08/24
1054+
+---------------+---------------+---------------+---------------+---------------+------*/
1055+
bool PyNameSpaceManager::IsRegisteredInPython(AStringCR attrName)
1056+
{
1057+
try
1058+
{
1059+
PyObject* modulesDict = PyImport_GetModuleDict();
1060+
PyObject* key, * value;
1061+
Py_ssize_t pos = 0;
1062+
1063+
while (PyDict_Next(modulesDict, &pos, &key, &value))
1064+
{
1065+
if (!PyModule_Check(value))
1066+
continue;
1067+
1068+
const char* moduleName = PyModule_GetName(value);
1069+
auto module = py::module_::import(moduleName);
1070+
1071+
if (py::hasattr(module, attrName.c_str()))
1072+
return true;
1073+
}
1074+
}
1075+
catch (py::error_already_set& e)
1076+
{
1077+
e.clear();
1078+
}
1079+
1080+
return false;
1081+
}
1082+
1083+
10201084
/*---------------------------------------------------------------------------------**//***
10211085
@bsimethod Chris Wu 05/24
10221086
+---------------+---------------+---------------+---------------+---------------+------*/

MSPythonSamples/3DModeling/SolidModification.py renamed to MSPythonSamples/3DModeling/SolidModification/SolidModification.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1558,7 +1558,7 @@ def primitiveToSmartSolid(bodyId):
15581558
return False
15591559

15601560
'''
1561-
Prerequisite: Open MSPythonSamples\data\SolidModeling.dgn
1561+
Prerequisite: Open MSPythonSamples\\data\\SolidModeling.dgn
15621562
'''
15631563
#main
15641564
if __name__ == "__main__":
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# -*- coding: utf-8 -*-
2+
'''
3+
/*--------------------------------------------------------------------------------------+
4+
| $Copyright: (c) 2024 Bentley Systems, Incorporated. All rights reserved. $
5+
+--------------------------------------------------------------------------------------*/
6+
'''
7+
8+
'''
9+
Running this sample needs to open GlassColor.dgn.
10+
This sample shows how to change the glass panels color from darker to lighter from the top row to bottom row.
11+
'''
12+
13+
from MSPyBentley import *
14+
from MSPyBentleyGeom import *
15+
from MSPyECObjects import *
16+
from MSPyDgnPlatform import *
17+
from MSPyMstnPlatform import *
18+
from MSPyDgnView import *
19+
import random
20+
21+
22+
''' Check whether the element color need to be changed. '''
23+
def needToChangeColor(msElement):
24+
# Element should be graphic, visible, not deleted and not construction
25+
if ((not msElement.ehdr.isGraphics) or msElement.hdr.dhdr.props.b.invisible
26+
or msElement.ehdr.deleted or msElement.hdr.dhdr.props.b.elementClass != 0):
27+
return False
28+
29+
# Element should be on level "A-GLAZ" or "A-WALL-METL"
30+
ret1 = Level.GetIdFromName (ISessionMgr.ActiveDgnModelRef, 0, "A-GLAZ")
31+
if(ret1[0] != BentleyStatus.eSUCCESS):
32+
return False
33+
ret2 = Level.GetIdFromName (ISessionMgr.ActiveDgnModelRef, 0, "A-WALL-METL")
34+
if(ret2[0] != BentleyStatus.eSUCCESS):
35+
return False
36+
37+
levelID1 = ret1[1]
38+
levelID2 = ret2[1]
39+
if(msElement.ehdr.level != levelID1 and msElement.ehdr.level != levelID2):
40+
return False
41+
42+
return True
43+
44+
def GetElementByXCoordinate():
45+
ACTIVEMODEL = ISessionMgr.ActiveDgnModelRef
46+
dgnModel = ACTIVEMODEL.GetDgnModel()
47+
graphicalElements = dgnModel.GetGraphicElements()
48+
categorizedElementsByX = {}
49+
for elementRef in graphicalElements:
50+
eeh = EditElementHandle(elementRef, dgnModel)
51+
msElement = eeh.GetElement ()
52+
53+
if(not needToChangeColor(msElement)):
54+
continue
55+
56+
# Categorize elements by z-coordinate
57+
xCoordinate = msElement.hdr.dhdr.range.xlowlim
58+
if round(xCoordinate/10000000) not in categorizedElementsByX:
59+
categorizedElementsByX[round(xCoordinate/10000000)] = []
60+
categorizedElementsByX[round(xCoordinate/10000000)].append(elementRef)
61+
62+
return categorizedElementsByX
63+
64+
''' Change the glass panels color '''
65+
def ChangeGlassWallColor(graphicalElements):
66+
ACTIVEMODEL = ISessionMgr.ActiveDgnModelRef
67+
dgnModel = ACTIVEMODEL.GetDgnModel()
68+
categorizedElements = {}
69+
for elementRef in graphicalElements:
70+
eeh = EditElementHandle(elementRef, dgnModel)
71+
msElement = eeh.GetElement ()
72+
73+
if(not needToChangeColor(msElement)):
74+
continue
75+
76+
# Categorize elements by z-coordinate
77+
zCoordinate = msElement.hdr.dhdr.range.zlowlim
78+
if zCoordinate not in categorizedElements:
79+
categorizedElements[zCoordinate] = []
80+
categorizedElements[zCoordinate].append(elementRef)
81+
82+
83+
color = 80
84+
transparency = 0
85+
# Change glass panels color for each row
86+
for zCoordinate in sorted(categorizedElements, reverse=True):
87+
for elementRef in categorizedElements[zCoordinate]:
88+
eeh = EditElementHandle(elementRef, dgnModel)
89+
propertiesSetter = ElementPropertiesSetter()
90+
propertiesSetter.SetColor(round(color))
91+
propertiesSetter.SetTransparency(transparency)
92+
if True == propertiesSetter.Apply(eeh):
93+
eeh.ReplaceInModel(elementRef)
94+
95+
if (len(categorizedElements) > 1):
96+
color += 15/(len(categorizedElements) - 1)
97+
transparency += 0.8/(len(categorizedElements) - 1)
98+
99+
def ChangeGlassColor():
100+
categorizedElementsByX = GetElementByXCoordinate()
101+
for xCoordinate in sorted(categorizedElementsByX, reverse=True):
102+
ChangeGlassWallColor(categorizedElementsByX[xCoordinate])
103+
104+
if __name__ == "__main__":
105+
ChangeGlassColor()
106+
107+

0 commit comments

Comments
 (0)