hi I'm trying to repack fbx file to a readable file for the Godot engine and I gat so far:
func fbx_to_scn(node):
var spi = Spatial.new()
add_child(spi)
spi.name = node
node = get_node(node+"/RootNode")
var ps
var mesh
for i in node.get_child_count():
if node.get_child(i).get_class() == "Skeleton":
ps = node.get_child(i)
elif node.get_child(i).get_class() == "MeshInstance":
mesh = node.get_child(i)
if not ps == null:
var new_sklet : Skeleton = Skeleton.new()
for i in ps.get_bone_count():
new_sklet.add_bone(ps.get_bone_name(i))
new_sklet.set_bone_rest(i,ps.get_bone_rest(i))
if ps.get_bone_parent(i) == -1:
continue
new_sklet.set_bone_parent(i,ps.get_bone_parent(i))
spi.add_child(new_sklet)
new_sklet.owner = spi
new_sklet.name = "Skeleton"
var mi = MeshInstance.new()
mi.name = "MeshInstance"
mi.mesh = mesh.mesh
spi.add_child(mi)
mi.owner = spi
if not ps == null:
mi.skeleton = "../Skeleton"
var pack = PackedScene.new()
pack.pack(spi)
if ResourceSaver.save("res://save_file/" +spi.name+ ".scn",pack) == OK:
print("file saved")
else:
print("some thing went wrong")
everything goes well and the file is created like this
but the rig is so bad
the left shape is the fbx file and the right is scn file
the rig is completely reverse and it's not even the same (had some changes)
Related
I am using the following function to implement a program that changes its behavior depending on the IP of the connected PC.
There is a problem with this function that if something tries to login and fails, it may get the IP of the failed one.
And now that we've encountered that possibility, the program is broken.
What edits do I need to make to make this function behave as expected?
import psutil
def get_ip(port=3389):
ip = ""
for x in psutil.net_connections():
if x.status == "ESTABLISHED" and x.laddr.port == port:
ip = x.raddr.ip
break
I changed the function based on Bijay Regmi's comment. Thank you. wmi was difficult for me, so I used win32evtlog to read it out little by little. I am working on improving readability and finding bugs little by little.
def systime(xml):
return datetime.fromisoformat(xml.find(f'{ns}System/{ns}TimeCreated').get('SystemTime')[:-2] + "+00:00")
def last_event(handle,
event_id,
condition: Callable[['Event'], bool] = None) -> Optional['Event']:
now = datetime.now(tz=timezone.utc)
while True:
events = win32evtlog.EvtNext(handle, 20)
if not events:
break
for event in events:
xml_content = win32evtlog.EvtRender(event, win32evtlog.EvtRenderEventXml)
obj = Event(ET.fromstring(xml_content))
if obj.EventID == event_id:
if obj.SystemTime + timedelta(minutes=5) < now:
return None
if condition and not condition(obj):
continue
return obj
class Event:
def __init__(self, xml: ET.Element):
self.EventID = xml and xml.find(f'{ns}System/{ns}EventID').text
self.SystemTime = xml and systime(xml)
self.xml = xml
if self.EventID == '24':
self.IpAddress = xml.find(f'{ns}UserData/{{Event_NS}}EventXML/{{Event_NS}}Address').text
elif self.EventID == '4624':
self.IpAddress = xml.find(f'{ns}EventData/{ns}Data[#Name="IpAddress"]').text
else:
self.IpAddress = None
I'd like to use nim to resize the default display resolution on a machine (windows 10 only), I want to basically do it via a command line call like setDisplay 1280 1024
I've seen and used the python example Resize display resolution using python with cross platform support which I can follow, but just can't translate. I just don't get how to fill in EnumDisplaySettings
import winim/lean
import strformat
var
cxScreen = GetSystemMetrics(SM_CXSCREEN)
cyScreen = GetSystemMetrics(SM_CYSCREEN)
msg = fmt"The screen is {cxScreen} pixels wide by {cyScreen} pixels high."
EnumDisplaySettings(Null,0, 0) #total type mismatch
MessageBox(0, msg, "Winim Example Screen Size", 0)
Tried checking stuff like https://cpp.hotexamples.com/fr/examples/-/-/EnumDisplaySettings/cpp-enumdisplaysettings-function-examples.html but wasn't much help, same for https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-changedisplaysettingsa
I wrote about 2% of this answer myself, and the rest came from pointystick on discord - thanks to them!
The solution is a bit lazy, but it's so fast that for most that won't matter.
With no cmd line args it will just set the display to the default recommendation, else with 2 cmd line args it can reset your display if it finds a match
import winim/lean
import os
import strutils
var modeToFind = (width: 1920, height: 1080, bitsPerPixel: 32,
refreshRate: 60)
var reset = 0
type ModeNotFoundError = object of CatchableError
proc getDisplayMode(): DEVMODEW =
## Finds the wanted screen resolution or raises a ModeNotFoundError.
var
nextMode: DWORD = 0
mode: DEVMODEW
while EnumDisplaySettings(nil, nextMode, mode) != 0:
echo $mode.dmPelsWidth & " x " & $mode.dmPelsHeight &
" x " & $mode.dmBitsPerPel &
" - " & $mode.dmDisplayFrequency
inc nextMode
if (mode.dmPelsWidth == modeToFind.width) and
(mode.dmPelsHeight == modeToFind.height):
echo "Found it!"
return mode
if(reset==1):
return mode
raise newException(ModeNotFoundError, "Cannot find wanted screen mode")
proc changeResolution(): bool =
## Actually changes the resolution. The return value indicates if it worked.
result = false
try:
let wantedMode = getDisplayMode()
result = ChangeDisplaySettings(wantedMode.unsafeAddr, 0.DWORD) == DISP_CHANGE_SUCCESSFUL
except ModeNotFoundError: discard
when isMainModule:
var
cxScreen:int32 = 0 #= GetSystemMetrics(SM_CXSCREEN)
cyScreen:int32 = 0 # = GetSystemMetrics(SM_CYSCREEN)
try:
cxScreen = (int32) parseInt(paramStr(1))
cyScreen = (int32) parseInt(paramStr(2))
modeToFind.width = cxScreen
modeToFind.height = cyScreen
except:
reset = 1
if not changeResolution():
echo "Change Resolution Failed"
I have this function who supposed to change the label of polygon (code below), where "nom_com" and "statutpro" are fields in a layer.
def ETIQUETAGE(self):
layer = self.COUCHE_DEPARTEMENT_SELECTIONNEE() #return a vector layer
deco = QgsPalLayerSettings()
deco.enabled = True
isExpression = True
if self.ChoixEtiquetage.currentText() == "COMMUNE":
deco.fieldName = '\'nom :\' +"nom_com"'
if self.ChoixEtiquetage.currentText() == "COMMUNE ET STATUT PROSPECTION":
deco.fieldName = '"nom_com" + \'\\n\' +"statutpro"'
labeler = QgsVectorLayerSimpleLabeling(deco)
layer.setLabeling(labeler)
layer.setLabelsEnabled(True)
layer.triggerRepaint()
When I run it everything ok (i don't have any error), the problem is for the display. The function change the label charateristic in the properties window but there is no display until I press aply in the properties window.
When I put only one argument the display work perfectly. for example
deco.fieldName = "nom_com"
Is there a particular syntax when it's a expression ?
I just see where my error was, it was a syntaxe error.
If the label is expression based we must put
deco.isExpression
for the plugin to display something in the canvas
def ETIQUETAGE(self):
layer = self.COUCHE_DEPARTEMENT_SELECTIONNEE() #return a vector layer
deco = QgsPalLayerSettings()
deco.enabled = True
deco.isExpression = True
if self.ChoixEtiquetage.currentText() == "COMMUNE":
deco.fieldName = "concat('nom : ', nom_com)"
if self.ChoixEtiquetage.currentText() == "COMMUNE ET STATUT PROSPECTION":
deco.fieldName = "concat('nom : ', nom_com, '\\n', 'Statut prospection : ', statutpro)"'
labeler = QgsVectorLayerSimpleLabeling(deco)
layer.setLabeling(labeler)
layer.setLabelsEnabled(True)
layer.triggerRepaint()
hope it will help people
I am trying to create a dashboard of data for our university, and have run into a problem with how it is presenting. I am using Bokeh and Python to create somewhat interactive graphs. My checkbox group is not updating when I click a box to select the college for the major. I have tried changing several items, but cannot figure out what I am doing wrong.
My code:
# Available college list
available_colleges = list(df['College'].unique())
source_maj = ColumnDataSource(df)
grouped_maj = df.groupby('Major').sum()
source_maj = ColumnDataSource(grouped_maj)
major = source_maj.data['Major'].tolist()
p_maj = figure(x_range=major, width=1100, height=500)
p_maj.xaxis.major_label_orientation = math.pi/4
color_map = factor_cmap(field_name='Major',
palette=Magma11, factors=level)
p_maj.vbar(x='Major', top='AY2018_19', source=source_maj, width=0.2, color=color_map)
p_maj.title.text ='Enrollment by Major'
p_maj.xaxis.axis_label = 'Major'
p_maj.yaxis.axis_label = 'Enrolled Students'
hover = HoverTool()
hover.tooltips = [
("2019-2020", "#AY2019_20"),
("2018-2019", "#AY2018_19"),
("2017-2018", "#AY2017_18")]
hover.mode = 'vline'
callback = CustomJS(args=dict(source=source_maj), code="""
const labels = cb_obj.labels;
const active = cb_obj.active;
const data = source_maj.data;
const sourceLen = data.combined.length;
const combined = Array(sourceLen).fill(undefined);
if (active.length > 0) {
const selectedColumns = labels.filter((val, ind) => active.includes(ind));
for(let i = 0; i < sourceLen; i++) {
let sum = 0;
for(col of selectedColumns){
sum += Major[col][i];
}
combined[i] = sum;
}
}
Major.combined=combined;
source_maj.change.emit();
""")
colleges_selection = CheckboxGroup(labels=available_colleges, active = [0], callback=callback)
controls = WidgetBox(colleges_selection)
p_maj = row(controls, p_maj)
Data is formated in a csv sheet that is being read
What it looks like, but nothing updates
Any help is greatly appreciated.
You'll probably want to watch the output the browser sends to the javascript console; it'll tell you what's going wrong here.
A couple places to start: your arguments to the CustomJS object bring in the python object 'source_maj' and rename it as 'source', but then in your JS code you refer to it as 'source_maj'. Also, your JS code makes reference to 'Major', but this isn't an object that the JS knows about (i.e. it wasn't brought in with the args).
I want to add xml to my .docx document using python-docx library. I tried this code from stackoverflow but it doesn't work, I don't know why. I get nothing when opening the docx with LibreOffice and Microsoft word.
table = document.add_table(rows=1, cols=1)
p = table.cell(0, 0).paragraphs[0]
run = p.add_run()
tag = run._r
start = docx.oxml.shared.OxmlElement('w:bookmarkStart')
start.set(docx.oxml.ns.qn('w:id'), '0')
start.set(docx.oxml.ns.qn('w:name'), '0')
tag.append(start)
ctype = docx.oxml.OxmlElement('w:complexType')
ctype.set(docx.oxml.ns.qn('w:name'), 'CT_FFCheckBox')
seq = docx.oxml.OxmlElement('w:sequence')
choice = docx.oxml.OxmlElement('w:choice')
el = docx.oxml.OxmlElement('w:element')
el.set(docx.oxml.ns.qn('w:name'), 'size')
el.set(docx.oxml.ns.qn('w:type'), 'CT_HpsMeasure')
el2 = docx.oxml.OxmlElement('w:element')
el2.set(docx.oxml.ns.qn('w:name'), 'sizeAuto')
el2.set(docx.oxml.ns.qn('w:type'), 'CT_OnOff')
choice.append(el)
choice.append(el2)
el3 = docx.oxml.OxmlElement('w:element')
el3.set(docx.oxml.ns.qn('w:name'), 'default')
el3.set(docx.oxml.ns.qn('w:type'), 'CT_OnOff')
el3.set(docx.oxml.ns.qn('w:minOccurs'), '0')
el4 = docx.oxml.OxmlElement('w:element')
el4.set(docx.oxml.ns.qn('w:name'), 'checked')
el4.set(docx.oxml.ns.qn('w:type'), 'CT_OnOff')
el4.set(docx.oxml.ns.qn('w:minOccurs'), '0')
seq.append(choice)
seq.append(el3)
seq.append(el4)
ctype.append(seq)
start.append(ctype)
end = docx.oxml.shared.OxmlElement('w:bookmarkEnd')
end.set(docx.oxml.ns.qn('w:id'), '0')
end.set(docx.oxml.ns.qn('w:name'), '0')
tag.append(end)
Can you help me? Thank you very much
PS : I find the code here
Tweaking the function from this SO post, I got this to work.
import docx
import random
def addCheckbox(para, box_id, name):
run = para.add_run()
tag = run._r
fld = docx.oxml.shared.OxmlElement('w:fldChar')
fld.set(docx.oxml.ns.qn('w:fldCharType'), 'begin')
ffData = docx.oxml.shared.OxmlElement('w:ffData')
e = docx.oxml.shared.OxmlElement('w:name')
e.set(docx.oxml.ns.qn('w:val'), 'Check1')
ffData.append(e)
ffData.append(docx.oxml.shared.OxmlElement('w:enabled'))
e = docx.oxml.shared.OxmlElement('w:calcOnExit')
e.set(docx.oxml.ns.qn('w:val'), '0')
ffData.append(e)
e = docx.oxml.shared.OxmlElement('w:checkBox')
e.append(docx.oxml.shared.OxmlElement('w:sizeAuto'))
ee = docx.oxml.shared.OxmlElement('w:default')
ee.set(docx.oxml.ns.qn('w:val'), '0')
e.append(ee)
ffData.append(e)
fld.append(ffData)
tag.append(fld)
run2 = para.add_run()
tag2 = run2._r
start = docx.oxml.shared.OxmlElement('w:bookmarkStart')
start.set(docx.oxml.ns.qn('w:id'), str(box_id))
start.set(docx.oxml.ns.qn('w:name'), name)
tag2.append(start)
run3 = para.add_run()
tag3 = run3._r
instr = docx.oxml.OxmlElement('w:instrText')
instr.text = 'FORMCHECKBOX'
tag3.append(instr)
run4 = para.add_run()
tag4 = run4._r
fld2 = docx.oxml.shared.OxmlElement('w:fldChar')
fld2.set(docx.oxml.ns.qn('w:fldCharType'), 'end')
tag4.append(fld2)
run5 = para.add_run()
tag5 = run5._r
end = docx.oxml.shared.OxmlElement('w:bookmarkEnd')
end.set(docx.oxml.ns.qn('w:id'), str(box_id))
end.set(docx.oxml.ns.qn('w:name'), name)
tag5.append(end)
if __name__ == '__main__':
document = docx.Document()
document.add_heading('Document Title', 0)
p1 = document.add_paragraph('A paragraph with a checkbox ')
addCheckbox(p1, random.randint(16*1024, 32*1024), 'justinwashere')
document.save('demo.docx')
I changed the contents of his ffData in the function to match the replacement XML in his original question.